fix(sdk/python): skip schema output dir for schema-free harness runs - #1072
Merged
santoshkumarradha merged 1 commit intoSep 25, 2026
Conversation
HarnessRunner.run() allocated the per-run .agentfield-out-* directory before dispatching the provider even when schema is None. That directory only ever holds .agentfield_output.json (Agent-Field#684, Agent-Field#891), and every consumer of it is already inside an `if schema is not None` guard, so a text-only run paid a filesystem write it never read back. When the project root could not accept one — a read-only mount, an immutable CI workspace — a plain permission_mode="plan" call failed during setup, before the coding agent was invoked at all. Allocate the directory only for schema-bearing runs. Their per-run isolation and cleanup are unchanged, so concurrent runs sharing one cwd still cannot overwrite or delete each other's output. Refs Agent-Field#684, Agent-Field#891
remote-controlled-man
requested review from
a team and
AbirAbbas
as code owners
September 25, 2026 02:18
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. |
santoshkumarradha
approved these changes
Sep 25, 2026
santoshkumarradha
left a comment
Member
There was a problem hiding this comment.
Validated the schema-free path and the existing schema-bearing harness flows locally. The focused tests, Ruff, compile checks, CLA, and CI are all green. This looks good to merge.
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
HarnessRunner.run()allocates the per-run.agentfield-out-*directory before dispatching the provider, even whenschema is None. That directory only ever holds.agentfield_output.json(#684, #891), and every consumer of it is already inside anif schema is not None:guard — so a text-only run pays a filesystem write it never reads, and aborts during setup when the project root cannot accept one. A plainpermission_mode="plan"call in a read-only checkout (immutable CI workspace, read-only mount) therefore fails before the coding agent is invoked at all. This allocates the directory only for schema-bearing runs, leaving their per-run isolation and cleanup exactly as they were.Type of change
Test plan
cd sdk/python && .venv/Scripts/python -B -m pytest tests/test_harness_runner.py -q -o addopts=''— 21 passed, including the new regression and the existing per-run isolation, concurrency, and cleanup-on-error tests.cd sdk/python && PYTHONUTF8=1 .venv/Scripts/python -B -m pytest tests -q -o addopts='' -k 'harness and not functional' -m 'not integration and not harness_live'— 308 passed, 2170 deselected, 0 failed, with no test files excluded.cd sdk/python && .venv/Scripts/python -B -m mypy --config-file mypy.ini agentfield/— Success: no issues found in 81 source files (the same command CI runs).cd sdk/python && .venv/Scripts/python -B -m ruff check .— All checks passed, at the CI-pinnedruff==0.15.22.cd sdk/python && .venv/Scripts/python -B -m ruff format --diff agentfield/harness/_runner.py tests/test_harness_runner.py— 2 files already formatted.cd sdk/python && PYTHONUTF8=1 .venv/Scripts/python -B -m pytest --ignore=tests/test_agent_mesh.py— 2391 passed, 7 failed, 7 skipped, 38 deselected in 190s, using the project's defaultaddopts.The new test fails on the unmodified runner at
_runner.py:302inos.makedirs(base_dir, exist_ok=True), before the provider is dispatched, and passes after the fix. It uses a real filesystem boundary rather than a mock:project_dirpoints below a regular file, so creating it raisesOSErroron every platform.Two things in that full run are pre-existing on this Windows machine, not caused by this PR, and both were confirmed by re-running them in a pristine
mainworktree: the 7 failures are all intests/test_log_writer.py(event-loop-blocking assertions from the #1066 area — identical 7 failed / 14 passed on unmodifiedmain), andtests/test_agent_mesh.pystalls after three tests when run as part of the suite (identical stall on unmodifiedmain; its fourth test passes in 0.55s in isolation). Neither file references the harness runner. Linux CI is the authority for both.Not run locally: the repo-wide coverage gate (
./scripts/coverage-summary.sh) aggregates Go, TypeScript, and web-ui surfaces that need toolchains this machine does not have, and./scripts/test-all.sh/ full CI were not run. Tests were executed on Windows with Python 3.13.12 in an isolateduv sync --frozen --extra devvenv;PYTHONUTF8=1is process-local and only affects how two packaging tests decodepyproject.tomlunder a non-UTF-8 host locale.Test coverage
The change adds a test and removes no code, and
agentfield.harnessis not among the default--covtargets inpyproject.toml, so nocoverage-baseline.jsonupdate should be needed.Checklist
The commit message is conventional. The signing box stays unchecked until the published head is actually signed. No issue is linked: this is a small self-discovered bug fix, and the contributing guide asks for an issue before large changes. Say the word if you would rather have one filed first.
Related issues / PRs
#684 established that the schema output file must live inside the agent root, and #891 gave each run its own temporary directory so concurrent runs sharing a cwd cannot overwrite or delete each other's output. Both guarantees are preserved here — they now apply to the runs that actually produce schema output.