Summary
real_api-marked tests are not deselected by default. Despite their docstrings claiming they are "opt-in / deselected by default", the only thing that excludes them is the hand-written marker expression in the CI/release workflows. Any other invocation — a plain pytest, pytest -m "not performance", or make test — runs them, which spawns real copilot CLI subprocesses and makes real API calls.
This is more than a hygiene issue: it can hard-kill a live conductor run --web-bg workflow. When an agent (e.g. the sdd-implementcoder) runs uv run pytest -m "not performance" from inside a running workflow, the real_api tests spin up competing copilot CLI subprocesses in the same process session as the workflow. That collides with the workflow's live Copilot session and the workflow process receives an unhandled SIGTERM — dying silently (no traceback, no faulthandler dump, PID file left behind, no workflow_failed event).
Reproduction
From a clean checkout (no real_api opt-in):
$ uv run pytest -q -m "not performance"...copilot._jsonrpc.JsonRpcError: JSON-RPC Error -32603: Request session.create failed with message: Model "claude-opus-4.7-1m-internal" is not available.WARNING conductor.providers.copilot:copilot.py:644 Agent 'writer' attempt 3/3 failed: ......FAILED tests/test_integration/test_copilot_large_write.py::test_large_create_tool_call_does_not_truncate1 failed, 4030 passed, 27 skipped, 29 deselected, ... in 126.75s
test_copilot_large_write is marked @pytest.mark.real_api and its module docstring says it is "opt-in (real_api marker, deselected by default)" — yet it ran and made a real session.create call.
Evidence / root cause
pyproject.toml[tool.pytest.ini_options] registers the real_api marker but sets no addopts to deselect it:
[tool.pytest.ini_options]
asyncio_mode = "auto"testpaths = ["tests"]
markers = [
"performance: ...",
"real_api: marks tests that make real API calls to external services (deselect with '-m \"not real_api\"')",
"install_scripts: ...",
]
# no addopts -> real_api runs by default
- Only CI hand-excludes them:
.github/workflows/ci.yml: uv run pytest ... -m "not real_api and not performance".github/workflows/release.yml: uv run pytest -m "not real_api and not performance"
Makefiletest: target is uv run pytest -m "not install_scripts" — does not exclude real_api.@pytest.mark.real_api tests today include at least:
tests/test_integration/test_copilot_large_write.pytests/test_integration/test_claude_real_api.py
Impact
- Local
make test / plain pytest is broken without real Copilot auth + the specific (internal) models available — a real_api test fails after 3 real retries. - Silent workflow kill: agents that run the test suite from inside a live
--web-bg run get the workflow hard-killed with no error surfaced (observed twice on sdd-implement; diagnosis: unhandled SIGTERM, PID file survived, no faulthandler/workflow_failed).
Proposed fix
Make real_api truly opt-in via a conftest.py collection hook (robust: it can't be accidentally re-enabled by a stray -m "not performance" the way a bare addopts = -m ... can, since pytest keeps only the last -m):
# tests/conftest.pydefpytest_collection_modifyitems(config, items):
marker_expr=config.getoption("-m") or""if"real_api"inmarker_expr:
return# explicitly requested -> run themskip=pytest.mark.skip(reason="real_api test: opt in with -m real_api")
foriteminitems:
if"real_api"initem.keywords:
item.add_marker(skip)With this in place:
make test, plain pytest, and the agent's pytest -m "not performance" all auto-skipreal_api — no real Copilot subprocesses spawned, so no interference with a live workflow, and local runs go green.pytest -m real_api still runs them explicitly.- CI's existing
-m "not real_api and not performance" continues to work unchanged.
Optionally also fix the now-accurate docstrings and consider adding --cov-neutral guidance.
Environment
- Conductor
v0.1.22 - Reproduced on Linux (WSL2), Python 3.12
Summary
real_api-marked tests are not deselected by default. Despite their docstrings claiming they are "opt-in / deselected by default", the only thing that excludes them is the hand-written marker expression in the CI/release workflows. Any other invocation — a plainpytest,pytest -m "not performance", ormake test— runs them, which spawns realcopilotCLI subprocesses and makes real API calls.This is more than a hygiene issue: it can hard-kill a live
conductor run --web-bgworkflow. When an agent (e.g. thesdd-implementcoder) runsuv run pytest -m "not performance"from inside a running workflow, thereal_apitests spin up competingcopilotCLI subprocesses in the same process session as the workflow. That collides with the workflow's live Copilot session and the workflow process receives an unhandledSIGTERM— dying silently (no traceback, nofaulthandlerdump, PID file left behind, noworkflow_failedevent).Reproduction
From a clean checkout (no
real_apiopt-in):test_copilot_large_writeis marked@pytest.mark.real_apiand its module docstring says it is "opt-in (real_apimarker, deselected by default)" — yet it ran and made a realsession.createcall.Evidence / root cause
pyproject.toml[tool.pytest.ini_options]registers thereal_apimarker but sets noaddoptsto deselect it:.github/workflows/ci.yml:uv run pytest ... -m "not real_api and not performance".github/workflows/release.yml:uv run pytest -m "not real_api and not performance"Makefiletest:target isuv run pytest -m "not install_scripts"— does not excludereal_api.@pytest.mark.real_apitests today include at least:tests/test_integration/test_copilot_large_write.pytests/test_integration/test_claude_real_api.pyImpact
make test/ plainpytestis broken without real Copilot auth + the specific (internal) models available — areal_apitest fails after 3 real retries.--web-bgrun get the workflow hard-killed with no error surfaced (observed twice onsdd-implement; diagnosis: unhandledSIGTERM, PID file survived, nofaulthandler/workflow_failed).Proposed fix
Make
real_apitruly opt-in via aconftest.pycollection hook (robust: it can't be accidentally re-enabled by a stray-m "not performance"the way a bareaddopts = -m ...can, since pytest keeps only the last-m):With this in place:
make test, plainpytest, and the agent'spytest -m "not performance"all auto-skipreal_api— no real Copilot subprocesses spawned, so no interference with a live workflow, and local runs go green.pytest -m real_apistill runs them explicitly.-m "not real_api and not performance"continues to work unchanged.Optionally also fix the now-accurate docstrings and consider adding
--cov-neutral guidance.Environment
v0.1.22