feat(harness): canonical dir model, unified permissions, incremental schema (Python)#689
Merged
santoshkumarradha merged 1 commit intoJun 24, 2026
Conversation
…schema (Python) Reworks the Python harness directory, permission, and schema-output contracts so they are consistent across all four providers and match the Go SDK. Directory model (#684, #686): - project_dir is the canonical agent root; cwd is the process dir. The schema output file always lands inside the agent root — when project_dir is set the runner places it in an isolated temp dir under project_dir (mirrors Go), so providers like OpenCode no longer reject it as an external-directory write. - opencode: --dir prefers project_dir over cwd (was inverted, the #684 bug). - codex: -C uses project_dir or cwd; added --skip-git-repo-check for non-repo working dirs. - gemini: removed the -C flag, which gemini rejects outright ("Unknown argument: C") and crashed every call; the root is now the process cwd. - claude-code: SDK cwd uses project_dir or cwd. - Terminal schema errors now include effective provider/project_dir/cwd/output. Permissions (#687): - codex: "auto" -> --sandbox workspace-write (was the deprecated --full-auto); "plan" -> --sandbox read-only. - gemini: "auto" -> --yolo (was --sandbox, which RESTRICTS execution and was backwards); "plan" -> --approval-mode plan. Incremental schema (#688): - New schema_mode: "single" (default) | "incremental" | "auto". - incremental builds the JSON object one top-level field at a time and recovers by patching only the missing/invalid fields instead of a full re-run. - auto switches to incremental above the large-schema threshold. Adds project_dir and schema_mode to app.harness() and HarnessConfig. Full harness test coverage for every provider's flag mapping and the incremental field-recovery path. Closes #684 Closes #686 Closes #687 Closes #688
Contributor
Performance
✓ No regressions detected |
Contributor
📊 Coverage gateThresholds from
✅ Gate passedNo surface regressed past the allowed threshold and the aggregate stayed above the floor. |
Contributor
📐 Patch coverage gateThreshold: 80% on lines this PR touches vs
✅ Patch gate passedEvery surface whose lines were touched by this PR has patch coverage at or above the threshold. |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
Reworks the Python harness so the directory, permission, and schema-output contracts are consistent across all four providers (claude-code, codex, gemini, opencode) and match the Go SDK reference. Defined in Python first; TS/Go ports tracked separately.
Closes #684
Closes #686
Closes #687
Closes #688
1. Directory model (#684, #686)
project_diris the canonical agent root;cwdis the process working dir. The schema output file always lands inside the agent root: whenproject_diris set the runner writes it to an isolated temp dir underproject_dir(mirrors the Go runner), so providers like OpenCode no longer reject it as anexternal_directorywrite.--dirnow prefersproject_dirovercwd(the precedence was inverted — the Python app.harness OpenCode project_dir/cwd schema output fails for nested workdir #684 bug).-Cusesproject_dir or cwd; added--skip-git-repo-checkso the harness can run in non-repo working dirs.-Cflag, which gemini rejects outright (Unknown argument: C) and crashed every call; the root is now the process cwd.cwdusesproject_dir or cwd.provider / project_dir / cwd / output_path(Python app.harness OpenCode project_dir/cwd schema output fails for nested workdir #684 ask Claude/build install script 011 c uqe6w5 e bj qknd w48f e9 n #5).2. Permissions (#687)
Canonical
permission_modecontract:None(safe default) |"auto"(autonomous, no prompts) |"plan"(read-only)."auto"→--sandbox workspace-write(was the now-deprecated--full-auto);"plan"→--sandbox read-only."auto"→--yolo(was--sandbox, which restricts execution — backwards);"plan"→--approval-mode plan.Flags were verified against installed
codex 0.141/gemini 0.40.1binaries plus upstream source, not from memory.3. Incremental schema (#688)
New
schema_mode:"single"(default, unchanged) |"incremental"|"auto".project_dirandschema_modeare now first-class params onapp.harness()andHarnessConfig.Test plan
ruff check .clean (the blocking CI lint).project_dirwins as--dir; runner-level Python app.harness OpenCode project_dir/cwd schema output fails for nested workdir #684 repro (nested cwd under shared root) places output under project_dir and validates.project_diris-Croot;plan→--sandbox read-only;--skip-git-repo-checkpresent.-C;project_diris the process cwd;auto→--yolo;plan→--approval-mode plan.project_dirused as SDK root overcwd.Not in this PR (follow-ups)
cwd-wins precedence) and Go (directory model already correct; needs the permission + incremental work).harness doctorpreflight (Harness provider availability: install extras +harness doctorpreflight + standardized missing-binary errors #685).