Real Local-Agent Smoke Runtime Hardening Implementation Plan
For agentic workers: REQUIRED SUB-SKILL: Use superpowers:subagent-driven-development (recommended) or superpowers:executing-plans to implement this plan task-by-task. Steps use checkbox (
- [ ]) syntax for tracking.
Goal: Add a release-grade, opt-in local-agent smoke path that proves materialized subject guidance is consumed by real task runs while keeping preview smoke as the safe default.
Architecture: Harden the existing tooling/scripts/run_subject_runtime_smoke.py runner instead of creating a parallel harness. Extend qiongli_task_run MCP argument mapping only where the smoke runner needs bounded real-run controls, then add report metadata, trace assertions, write-boundary checks, and release-readiness documentation around the existing real orchestrator path.
Tech Stack: Python 3.11+, stdlib unittest, tempfile, pathlib, existing Qiongli MCP handler/orchestrator bridge, existing uv run python -m unittest, JSON smoke reports.
Source Spec
Implement:
docs/superpowers/specs/2026-07-02-real-local-agent-smoke-runtime-hardening-design.md
Do not add new subjects. Do not make local-agent smoke part of the default test or release gate. Keep preview mode safe and unchanged by default.
File Map
- Modify
tooling/scripts/run_subject_runtime_smoke.py- Owns smoke case selection, isolated environment setup, task-run argument construction, local-agent guardrails, local-agent assertions, write-boundary checks, rerun diagnostics, and JSON report shape.
- Modify
tests/test_subject_runtime_smoke.py- Adds focused unit tests for local-agent default case selection, bounded task args, trace assertions, write-boundary failures, and error reports.
- Modify
packages/python-qiongli/src/qiongli/bridges/mcp_tool_handlers.py- Extends
qiongli_task_runinput schema and_task_run_kwargs()to pass bounded real-run options through toModelOrchestrator.task_run().
- Extends
- Modify
tests/test_mcp_tool_handlers.py- Adds coverage that
max_revision_rounds,output_budget, andskip_validationare accepted by MCP and passed to the orchestrator.
- Adds coverage that
- Modify
docs/advanced/publish-pypi.md- Documents the optional subject local-agent smoke command for maintainers and release candidates.
- Modify
docs/zh/advanced/publish-pypi.md- Chinese documentation parity for the same maintainer-only smoke command.
Task 0: Prepare Worktree And Baseline
Files:
No source files changed.
[ ] Step 1: Confirm current branch and cleanliness
Run from repository root:
git status --short --branchExpected: current branch is dev and no uncommitted source changes are present.
- [ ] Step 2: Confirm
.worktreesis ignored
Run:
git check-ignore -q .worktreesExpected: exit code 0.
- [ ] Step 3: Create an isolated implementation worktree
Run:
git worktree add .worktrees/real-local-agent-smoke-hardening -b feature/real-local-agent-smoke-hardening devExpected: output includes Preparing worktree.
- [ ] Step 4: Run baseline focused tests in the worktree
Run from .worktrees/real-local-agent-smoke-hardening:
uv run python -m unittest tests.test_subject_runtime_smoke tests.test_mcp_tool_handlersExpected: all selected tests pass before implementation.
- [ ] Step 5: Run baseline subject smoke commands
Run:
uv run python tooling/scripts/run_subject_runtime_smoke.py --json
uv run python tooling/scripts/evaluate_subject_router.py --jsonExpected: preview smoke exits 0 with summary.failed == 0; router eval exits 0 with no threshold failures.
Task 1: Smoke Runner Selection And Schema Helpers
Files:
Modify:
tooling/scripts/run_subject_runtime_smoke.pyModify:
tests/test_subject_runtime_smoke.py[ ] Step 1: Write failing tests for schema version and local-agent default case selection
Add imports in tests/test_subject_runtime_smoke.py:
from tooling.scripts import run_subject_runtime_smoke as smokeAdd these tests to SubjectRuntimeSmokeTests:
def test_report_schema_version_is_1_1(self) -> None:
with tempfile.TemporaryDirectory() as tmp_dir:
report = run_smoke_suite(
fixture_dir=FIXTURE_DIR,
workspace_root=Path(tmp_dir),
mode="preview",
selected_cases=["suggest_finance_subject"],
)
self.assertEqual(report["schema_version"], "1.1")
def test_local_agent_mode_defaults_to_confirmed_finance_case(self) -> None:
fake_result = {
"name": "confirmed_finance_guidance_loaded",
"source": "tests/fixtures/subject_runtime_smoke/confirmed_finance_guidance_loaded.json",
"project_root": "/tmp/project",
"status": "passed",
"failures": [],
"environment": {},
"result": {"run_agents": True, "data": {}},
"local_agent": {"requested": True, "env_opt_in": True},
"trace_assertions": {},
"write_boundary": {"known_paths_inside_project": True, "violations": []},
}
with tempfile.TemporaryDirectory() as tmp_dir:
with mock.patch.dict("os.environ", {smoke.LOCAL_AGENT_ENV: "1"}):
with mock.patch.object(smoke, "run_smoke_case", return_value=fake_result) as run_case:
report = run_smoke_suite(
fixture_dir=FIXTURE_DIR,
workspace_root=Path(tmp_dir),
mode="local-agent",
selected_cases=[],
)
self.assertEqual(report["schema_version"], "1.1")
self.assertEqual(report["summary"], {"total": 1, "passed": 1, "failed": 0})
self.assertEqual(run_case.call_count, 1)
selected_case = run_case.call_args.args[0]
self.assertEqual(selected_case.name, "confirmed_finance_guidance_loaded")- [ ] Step 2: Run tests to verify they fail
Run:
uv run python -m unittest tests.test_subject_runtime_smokeExpected: failures mention schema_version still being 1.0 and local-agent mode selecting all cases when no --case is provided.
- [ ] Step 3: Add constants and a case selection helper
In tooling/scripts/run_subject_runtime_smoke.py, replace the hard-coded schema version with constants near the existing LOCAL_AGENT_ENV constant:
REPORT_SCHEMA_VERSION = "1.1"
LOCAL_AGENT_DEFAULT_CASES = ("confirmed_finance_guidance_loaded",)Add this helper below load_smoke_cases():
def _select_smoke_cases(
cases: list[SmokeCase],
*,
mode: str,
selected_cases: list[str] | None,
) -> list[SmokeCase]:
selected = set(selected_cases or [])
if mode == "local-agent" and not selected:
selected = set(LOCAL_AGENT_DEFAULT_CASES)
if selected:
filtered = [case for case in cases if case.name in selected]
found = {case.name for case in filtered}
missing = sorted(selected - found)
if missing:
raise ValueError("unknown smoke case(s): " + ", ".join(missing))
return filtered
return list(cases)In run_smoke_suite(), replace the inline selection block with:
cases = _select_smoke_cases(
load_smoke_cases(fixture_dir),
mode=mode,
selected_cases=selected_cases,
)Set report schema version via the constant:
"schema_version": REPORT_SCHEMA_VERSION,Update _error_report() to also use REPORT_SCHEMA_VERSION.
- [ ] Step 4: Run tests to verify Task 1 passes
Run:
uv run python -m unittest tests.test_subject_runtime_smokeExpected: test_report_schema_version_is_1_1 and test_local_agent_mode_defaults_to_confirmed_finance_case pass, with no regression in existing smoke tests.
- [ ] Step 5: Commit Task 1
Run:
git add tooling/scripts/run_subject_runtime_smoke.py tests/test_subject_runtime_smoke.py
git commit -m "test(smoke): default local-agent subject smoke case"Task 2: Pass Bounded Task-Run Options Through MCP
Files:
Modify:
packages/python-qiongli/src/qiongli/bridges/mcp_tool_handlers.pyModify:
tests/test_mcp_tool_handlers.py[ ] Step 1: Write failing MCP passthrough test
Add this test near test_task_run_tool_can_launch_agents_when_explicitly_enabled in tests/test_mcp_tool_handlers.py:
def test_task_run_tool_passes_bounded_runtime_options(self) -> None:
class StubResult:
mode = "task-run"
confidence = 0.95
merged_analysis = "run ok"
recommendations: list[str] = []
data = {"runtime_plan": {"draft": "codex", "review": "codex"}}
class StubOrchestrator:
def task_run(self, **kwargs: object) -> StubResult:
self.kwargs = kwargs
return StubResult()
stub = StubOrchestrator()
with tempfile.TemporaryDirectory() as tmp_dir:
root = Path(tmp_dir)
with mock.patch.object(tool_handlers, "ModelOrchestrator", return_value=stub):
result = call_qiongli_tool(
"qiongli_task_run",
{
"cwd": str(root),
"task_id": "C1",
"paper_type": "empirical",
"topic": "smoke topic",
"run_agents": True,
"max_revision_rounds": 0,
"output_budget": 1,
"skip_validation": True,
},
)
self.assertFalse(result["isError"])
self.assertEqual(stub.kwargs["max_revision_rounds"], 0)
self.assertEqual(stub.kwargs["output_budget"], 1)
self.assertIs(stub.kwargs["skip_validation"], True)- [ ] Step 2: Run the focused test to verify it fails
Run:
uv run python -m unittest tests.test_mcp_tool_handlers.MCPToolHandlerTests.test_task_run_tool_passes_bounded_runtime_optionsExpected: failure because the MCP schema or _task_run_kwargs() does not accept or pass the new fields.
- [ ] Step 3: Extend the
qiongli_task_runschema
In packages/python-qiongli/src/qiongli/bridges/mcp_tool_handlers.py, add these properties to the qiongli_task_run input schema:
"max_revision_rounds": {"type": "integer", "minimum": 0},
"output_budget": {"type": "integer", "minimum": 1},
"skip_validation": {"type": "boolean"},- [ ] Step 4: Add integer argument parsing helpers
Near _optional_bool() in mcp_tool_handlers.py, add:
def _optional_int(
args: dict[str, Any],
key: str,
default: int | None = None,
*,
minimum: int | None = None,
) -> int | None:
if key not in args or args[key] is None:
return default
raw = args[key]
if isinstance(raw, bool) or not isinstance(raw, int):
raise ValueError(f"{key} must be an integer")
if minimum is not None and raw < minimum:
raise ValueError(f"{key} must be >= {minimum}")
return rawIf the file already has an equivalent integer helper, reuse it and do not add a duplicate.
- [ ] Step 5: Pass bounded options through
_task_run_kwargs()
In _task_run_kwargs(), add these fields to the returned dict:
"max_revision_rounds": _optional_int(args, "max_revision_rounds", 2, minimum=0),
"output_budget": _optional_int(args, "output_budget", None, minimum=1),
"skip_validation": _optional_bool(args, "skip_validation", default=False),Do not pass these only in local-agent mode. The handler should map valid arguments consistently; preview mode will ignore them because it calls task_plan().
- [ ] Step 6: Run MCP tests
Run:
uv run python -m unittest tests.test_mcp_tool_handlersExpected: all MCP handler tests pass, including the new bounded runtime options test.
- [ ] Step 7: Commit Task 2
Run:
git add packages/python-qiongli/src/qiongli/bridges/mcp_tool_handlers.py tests/test_mcp_tool_handlers.py
git commit -m "feat(mcp): pass bounded task-run options"Task 3: Bounded Local-Agent Task Arguments
Files:
Modify:
tooling/scripts/run_subject_runtime_smoke.pyModify:
tests/test_subject_runtime_smoke.py[ ] Step 1: Write failing tests for local-agent task arguments
Add this test to tests/test_subject_runtime_smoke.py:
def test_local_agent_case_uses_bounded_task_arguments(self) -> None:
captured_calls: list[tuple[str, dict[str, object]]] = []
def fake_call(name: str, args: dict[str, object]) -> dict[str, object]:
captured_calls.append((name, dict(args)))
if name == "qiongli_subject_update":
return {"structuredContent": {"ok": True}, "isError": False}
return {
"structuredContent": {
"mode": "task-run",
"run_agents": True,
"data": {
"task_packet": {
"local_guidance": {
"guidance_files_read": [
".qiongli/guidance.d/subject-runtime.md"
]
},
"subject_refinement": {
"decision": "confirm_subject",
"primary_subject": "finance",
"loaded_resources": {
"levels": ["subject_overlay", "subject_skill"]
},
"signals": [],
"resource_activation_plan": {},
},
"runtime_plan": {
"primary_agent": "codex",
"review_agent": "codex",
"fallback_agent": "codex",
},
"domain": "finance",
},
"local_guidance_trace": {
"run_dir": ".qiongli/trace/runs/run-1",
"trace_index": ".qiongli/trace/index.jsonl",
"guidance_files_read": [
".qiongli/guidance.d/subject-runtime.md"
],
},
"routing_notes": ["Runtime plan: draft=codex, review=codex."],
},
},
"isError": False,
}
case = SmokeCase(
name="confirmed_finance_guidance_loaded",
manifest=None,
args={
"task_id": "C1",
"paper_type": "empirical",
"topic": "earnings announcement stock market reaction",
"context": "Use event-study evidence and Journal of Finance standards.",
"domain": "auto",
"guidance_mode": "propose",
"run_agents": False,
},
expected={
"run_agents": False,
"decision": "confirm_subject",
"primary_subject": "finance",
"effective_domain": "finance",
"resource_levels": ["subject_overlay", "subject_skill"],
"guidance_source": ".qiongli/guidance.d/subject-runtime.md",
},
source=Path("confirmed_finance_guidance_loaded.json"),
setup_subject_action={
"action": "confirm",
"subject": "finance",
"run_id": "setup-confirm-finance",
},
)
with tempfile.TemporaryDirectory() as tmp_dir:
with mock.patch.object(smoke, "call_qiongli_tool", side_effect=fake_call):
result = smoke.run_smoke_case(case, Path(tmp_dir), "local-agent")
self.assertEqual(result["status"], "passed", result["failures"])
task_call = captured_calls[-1]
self.assertEqual(task_call[0], "qiongli_task_run")
task_args = task_call[1]
self.assertIs(task_args["run_agents"], True)
self.assertEqual(task_args["max_revision_rounds"], 0)
self.assertEqual(task_args["output_budget"], 1)
self.assertIs(task_args["skip_validation"], True)
self.assertEqual(task_args["execution_mode"], "solo")
self.assertEqual(task_args["controller"], "codex")
self.assertEqual(task_args["primary"], "codex")
self.assertEqual(task_args["reviewer"], "codex")- [ ] Step 2: Run the focused test to verify it fails
Run:
uv run python -m unittest tests.test_subject_runtime_smoke.SubjectRuntimeSmokeTests.test_local_agent_case_uses_bounded_task_argumentsExpected: failure because local-agent mode only sets run_agents today.
- [ ] Step 3: Add local-agent bounded argument constants
In tooling/scripts/run_subject_runtime_smoke.py, add near the other constants:
SUBJECT_GUIDANCE_SOURCE = ".qiongli/guidance.d/subject-runtime.md"
LOCAL_AGENT_TASK_OVERRIDES: dict[str, Any] = {
"run_agents": True,
"max_revision_rounds": 0,
"output_budget": 1,
"skip_validation": True,
"execution_mode": "solo",
"controller": "codex",
"primary": "codex",
"reviewer": "codex",
"solo_role_gates": "standard",
}- [ ] Step 4: Add task argument builder and local-agent run expectation
Add below _isolated_env():
def _task_run_args_for_mode(case: SmokeCase, project_root: Path, mode: str) -> dict[str, Any]:
args = dict(case.args)
args["cwd"] = str(project_root)
if mode == "local-agent":
args.update(LOCAL_AGENT_TASK_OVERRIDES)
else:
args["run_agents"] = False
return argsIn run_smoke_case(), replace the inline task args block with:
args = _task_run_args_for_mode(case, project_root, mode)
result = call_qiongli_tool("qiongli_task_run", args)Change the assertion call in run_smoke_case() from:
failures = _assert_case(case, result)to:
failures = _assert_case(case, result, mode=mode)Change the helper signature:
def _assert_case(
case: SmokeCase,
result: dict[str, Any],
*,
mode: str = "preview",
) -> list[str]:Replace the run_agents comparison inside _assert_case() with:
expected_run_agents = True if mode == "local-agent" else expected.get("run_agents")
_expect_equal(failures, "run_agents", payload.get("run_agents"), expected_run_agents)- [ ] Step 5: Run smoke runner tests
Run:
uv run python -m unittest tests.test_subject_runtime_smokeExpected: all subject runtime smoke tests pass.
- [ ] Step 6: Commit Task 3
Run:
git add tooling/scripts/run_subject_runtime_smoke.py tests/test_subject_runtime_smoke.py
git commit -m "feat(smoke): bound local-agent subject smoke runs"Task 4: Local-Agent Assertions And Report Metadata
Files:
Modify:
tooling/scripts/run_subject_runtime_smoke.pyModify:
tests/test_subject_runtime_smoke.py[ ] Step 1: Write failing tests for local-agent assertion failures and metadata
Add these tests to tests/test_subject_runtime_smoke.py:
def test_local_agent_assertion_requires_guidance_trace(self) -> None:
case = SmokeCase(
name="confirmed_finance_guidance_loaded",
manifest=None,
args={},
expected={
"run_agents": True,
"decision": "confirm_subject",
"primary_subject": "finance",
"effective_domain": "finance",
"resource_levels": [],
"guidance_source": ".qiongli/guidance.d/subject-runtime.md",
},
source=Path("confirmed_finance_guidance_loaded.json"),
)
result = {
"structuredContent": {
"run_agents": True,
"data": {
"task_packet": {
"local_guidance": {
"guidance_files_read": [
".qiongli/guidance.d/subject-runtime.md"
]
},
"subject_refinement": {
"decision": "confirm_subject",
"primary_subject": "finance",
"loaded_resources": {"levels": []},
"signals": [],
"resource_activation_plan": {},
},
"domain": "finance",
}
},
}
}
failures = smoke._assert_case(case, result, mode="local-agent", project_root=Path("/tmp/project"))
self.assertIn("missing local guidance trace", failures)
def test_local_agent_report_includes_runtime_metadata(self) -> None:
case = next(
item
for item in load_smoke_cases(FIXTURE_DIR)
if item.name == "confirmed_finance_guidance_loaded"
)
def fake_call(name: str, args: dict[str, object]) -> dict[str, object]:
if name == "qiongli_subject_update":
return {"structuredContent": {"ok": True}, "isError": False}
return {
"structuredContent": {
"mode": "task-run",
"run_agents": True,
"data": {
"task_packet": {
"local_guidance": {
"guidance_files_read": [
".qiongli/guidance.d/subject-runtime.md"
]
},
"subject_refinement": {
"decision": "confirm_subject",
"primary_subject": "finance",
"loaded_resources": {
"levels": ["subject_overlay", "subject_skill"]
},
"signals": [],
"resource_activation_plan": {},
},
"runtime_plan": {
"primary_agent": "codex",
"review_agent": "codex",
"fallback_agent": "codex",
},
"domain": "finance",
},
"local_guidance_trace": {
"run_dir": ".qiongli/trace/runs/run-1",
"trace_index": ".qiongli/trace/index.jsonl",
"guidance_files_read": [
".qiongli/guidance.d/subject-runtime.md"
],
},
"routing_notes": ["Runtime plan: draft=codex, review=codex."],
},
},
"isError": False,
}
with tempfile.TemporaryDirectory() as tmp_dir:
with mock.patch.object(smoke, "call_qiongli_tool", side_effect=fake_call):
result = smoke.run_smoke_case(case, Path(tmp_dir), "local-agent")
self.assertEqual(result["status"], "passed", result["failures"])
self.assertEqual(
result["local_agent"]["runtime_plan"],
{"primary_agent": "codex", "review_agent": "codex", "fallback_agent": "codex"},
)
self.assertTrue(result["trace_assertions"]["trace_written"])
self.assertTrue(result["trace_assertions"]["subject_guidance_loaded"])
self.assertTrue(result["trace_assertions"]["subject_refinement_persisted"])- [ ] Step 2: Run the focused tests to verify they fail
Run:
uv run python -m unittest \
tests.test_subject_runtime_smoke.SubjectRuntimeSmokeTests.test_local_agent_assertion_requires_guidance_trace \
tests.test_subject_runtime_smoke.SubjectRuntimeSmokeTests.test_local_agent_report_includes_runtime_metadataExpected: failures because _assert_case() does not accept project_root yet and the case report has no local_agent or trace_assertions metadata.
- [ ] Step 3: Extend
_assert_case()with project-root context
In run_smoke_case(), change the Task 3 assertion call from:
failures = _assert_case(case, result, mode=mode)to:
payload = result.get("structuredContent", result)
failures = _assert_case(case, result, mode=mode, project_root=project_root)Change the helper signature from the Task 3 version to:
def _assert_case(
case: SmokeCase,
result: dict[str, Any],
*,
mode: str = "preview",
project_root: Path | None = None,
) -> list[str]:Existing tests that call _assert_case(case, result) should continue to work because both new arguments have defaults.
- [ ] Step 4: Add local-agent metadata helpers
Add these helpers below _expect_equal():
def _payload_data(payload: dict[str, Any]) -> dict[str, Any]:
data = payload.get("data", {})
return data if isinstance(data, dict) else {}
def _task_packet_from_payload(payload: dict[str, Any]) -> dict[str, Any]:
data = _payload_data(payload)
packet = data.get("task_packet", {})
return packet if isinstance(packet, dict) else {}
def _local_guidance_trace_from_payload(payload: dict[str, Any]) -> dict[str, Any]:
data = _payload_data(payload)
trace = data.get("local_guidance_trace", {})
return trace if isinstance(trace, dict) else {}
def _local_agent_metadata(payload: dict[str, Any]) -> dict[str, Any]:
packet = _task_packet_from_payload(payload)
return {
"requested": True,
"env_opt_in": os.environ.get(LOCAL_AGENT_ENV) == "1",
"will_launch_agents": bool(payload.get("run_agents")),
"runtime_plan": dict(packet.get("runtime_plan", {}) or {}),
}
def _trace_assertions(payload: dict[str, Any]) -> dict[str, bool]:
packet = _task_packet_from_payload(payload)
guidance = packet.get("local_guidance", {})
if not isinstance(guidance, dict):
guidance = {}
trace = _local_guidance_trace_from_payload(payload)
files_read = list(guidance.get("guidance_files_read", []) or [])
trace_files_read = list(trace.get("guidance_files_read", []) or [])
subject_guidance_loaded = (
SUBJECT_GUIDANCE_SOURCE in files_read
or SUBJECT_GUIDANCE_SOURCE in trace_files_read
)
return {
"trace_written": bool(trace),
"subject_guidance_loaded": subject_guidance_loaded,
"subject_refinement_persisted": isinstance(packet.get("subject_refinement"), dict),
}- [ ] Step 5: Add local-agent assertion checks
Near the end of _assert_case(), add:
if mode == "local-agent":
trace = _local_guidance_trace_from_payload(payload)
trace_assertions = _trace_assertions(payload)
if not trace:
failures.append("missing local guidance trace")
if expected.get("guidance_source") and not trace_assertions["subject_guidance_loaded"]:
failures.append(
f"missing local-agent guidance source {expected['guidance_source']!r}"
)
if not trace_assertions["subject_refinement_persisted"]:
failures.append("missing local-agent subject refinement packet")- [ ] Step 6: Include metadata in case reports
In run_smoke_case(), after payload = result.get("structuredContent", result), build the base report:
report = {
"name": case.name,
"source": _repo_relative(case.source),
"project_root": str(project_root),
"status": "passed" if not failures else "failed",
"failures": failures,
"environment": env_updates,
"result": payload,
}
if mode == "local-agent":
report["local_agent"] = _local_agent_metadata(payload)
report["trace_assertions"] = _trace_assertions(payload)
return reportRemove or replace the existing direct return dict at the end of run_smoke_case().
- [ ] Step 7: Run smoke tests
Run:
uv run python -m unittest tests.test_subject_runtime_smokeExpected: all subject runtime smoke tests pass.
- [ ] Step 8: Commit Task 4
Run:
git add tooling/scripts/run_subject_runtime_smoke.py tests/test_subject_runtime_smoke.py
git commit -m "feat(smoke): report local-agent trace assertions"Task 5: Write-Boundary Checks And Rerun Diagnostics
Files:
Modify:
tooling/scripts/run_subject_runtime_smoke.pyModify:
tests/test_subject_runtime_smoke.py[ ] Step 1: Write failing tests for write-boundary checks
Add these tests to tests/test_subject_runtime_smoke.py:
def test_write_boundary_detects_outside_trace_path(self) -> None:
project_root = Path("/tmp/project").resolve()
payload = {
"data": {
"local_guidance_trace": {
"run_dir": "/tmp/outside/run-1",
"trace_index": ".qiongli/trace/index.jsonl",
}
}
}
result = smoke._write_boundary_report(payload, project_root)
self.assertFalse(result["known_paths_inside_project"])
self.assertTrue(any("/tmp/outside/run-1" in item for item in result["violations"]))
def test_error_report_includes_rerun_command(self) -> None:
error = RuntimeError("local-agent smoke requires QIONGLI_SMOKE_RUN_AGENTS=1")
report = smoke._error_report("local-agent", error)
self.assertEqual(report["schema_version"], "1.1")
self.assertIn("rerun_command", report)
self.assertIn("QIONGLI_SMOKE_RUN_AGENTS=1", report["rerun_command"])
self.assertIn("--mode local-agent", report["rerun_command"])- [ ] Step 2: Run tests to verify they fail
Run:
uv run python -m unittest \
tests.test_subject_runtime_smoke.SubjectRuntimeSmokeTests.test_write_boundary_detects_outside_trace_path \
tests.test_subject_runtime_smoke.SubjectRuntimeSmokeTests.test_error_report_includes_rerun_commandExpected: failures because _write_boundary_report() does not exist and _error_report() has no rerun command.
- [ ] Step 3: Add path resolution helpers
In tooling/scripts/run_subject_runtime_smoke.py, add below _repo_relative():
def _resolve_reported_path(project_root: Path, value: Any) -> Path | None:
if not isinstance(value, str) or not value.strip():
return None
raw = Path(value)
return raw.resolve() if raw.is_absolute() else (project_root / raw).resolve()
def _path_inside_project(project_root: Path, path: Path) -> bool:
try:
path.relative_to(project_root.resolve())
return True
except ValueError:
return False- [ ] Step 4: Add write-boundary report helper
Add below the path helpers:
def _write_boundary_report(payload: dict[str, Any], project_root: Path) -> dict[str, Any]:
violations: list[str] = []
expected_paths = [
".qiongli/guidance_manifest.yaml",
SUBJECT_GUIDANCE_SOURCE,
".qiongli/trace",
]
for rel_path in expected_paths:
resolved = (project_root / rel_path).resolve()
if not _path_inside_project(project_root, resolved):
violations.append(str(resolved))
trace = _local_guidance_trace_from_payload(payload)
for key in ("run_dir", "trace_index", "proposal_path"):
resolved = _resolve_reported_path(project_root, trace.get(key))
if resolved is not None and not _path_inside_project(project_root, resolved):
violations.append(str(resolved))
return {
"known_paths_inside_project": not violations,
"violations": violations,
}- [ ] Step 5: Include write-boundary report in local-agent case reports and failures
In run_smoke_case(), when mode == "local-agent", add:
write_boundary = _write_boundary_report(payload, project_root)
report["write_boundary"] = write_boundary
if not write_boundary["known_paths_inside_project"]:
report["status"] = "failed"
report["failures"].extend(
f"write boundary violation: {item}"
for item in write_boundary["violations"]
)Ensure this runs after the base report is built.
- [ ] Step 6: Add rerun command helper
Add near _error_report():
def _rerun_command(mode: str, case_name: str | None = None) -> str:
parts = [
"uv",
"run",
"python",
"tooling/scripts/run_subject_runtime_smoke.py",
"--mode",
mode,
]
if case_name:
parts.extend(["--case", case_name])
parts.append("--json")
command = " ".join(parts)
if mode == "local-agent":
command = f"{LOCAL_AGENT_ENV}=1 {command}"
return commandUpdate _error_report():
"rerun_command": _rerun_command(mode),When a specific local-agent case fails inside run_smoke_case(), include:
report["rerun_command"] = _rerun_command(mode, case.name)- [ ] Step 7: Run smoke tests
Run:
uv run python -m unittest tests.test_subject_runtime_smokeExpected: all smoke tests pass.
- [ ] Step 8: Commit Task 5
Run:
git add tooling/scripts/run_subject_runtime_smoke.py tests/test_subject_runtime_smoke.py
git commit -m "feat(smoke): audit local-agent write boundaries"Task 6: Release-Readiness Documentation
Files:
Modify:
docs/advanced/publish-pypi.mdModify:
docs/zh/advanced/publish-pypi.md[ ] Step 1: Add English maintainer smoke documentation
In docs/advanced/publish-pypi.md, add a short subsection near the existing release smoke documentation:
### Optional subject runtime local-agent smoke
The default release smoke remains preview-first and does not launch local
agents. Before a release candidate, maintainers can additionally verify the
adaptive subject runtime with a real local-agent run:
```bash
uv run python tooling/scripts/run_subject_runtime_smoke.py --json
uv run python tooling/scripts/evaluate_subject_router.py --json
QIONGLI_SMOKE_RUN_AGENTS=1 \
uv run python tooling/scripts/run_subject_runtime_smoke.py \
--mode local-agent \
--case confirmed_finance_guidance_loaded \
--jsonThe local-agent command is opt-in and should be treated as a maintainer confidence check. It verifies that confirmed subject guidance is loaded through .qiongli/guidance.d/subject-runtime.md, that a local guidance trace is written, and that Qiongli-visible paths remain inside the isolated smoke root.
- [ ] **Step 2: Add Chinese maintainer smoke documentation**
In `docs/zh/advanced/publish-pypi.md`, add the Chinese equivalent near the
existing release smoke documentation:
```markdown
### 可选的 subject runtime 本地 agent smoke
默认 release smoke 仍然是 preview-first,不会启动本地 agent。发布候选版本前,
维护者可以额外运行一次真实本地 agent smoke 来验证 adaptive subject runtime:
```bash
uv run python tooling/scripts/run_subject_runtime_smoke.py --json
uv run python tooling/scripts/evaluate_subject_router.py --json
QIONGLI_SMOKE_RUN_AGENTS=1 \
uv run python tooling/scripts/run_subject_runtime_smoke.py \
--mode local-agent \
--case confirmed_finance_guidance_loaded \
--json这个 local-agent 命令必须显式 opt in,只作为维护者信心检查。它会验证已确认 subject 的 .qiongli/guidance.d/subject-runtime.md 被真实 task run 加载、 local guidance trace 已写入,并且 Qiongli 可见路径仍在隔离 smoke root 内。
- [ ] **Step 3: Run doc checks**
Run:
```bash
rg -n "QIONGLI_SMOKE_RUN_AGENTS=1|confirmed_finance_guidance_loaded" docs/advanced/publish-pypi.md docs/zh/advanced/publish-pypi.md
git diff --checkExpected: both docs contain the command and git diff --check exits 0.
- [ ] Step 4: Commit Task 6
Run:
git add docs/advanced/publish-pypi.md docs/zh/advanced/publish-pypi.md
git commit -m "docs(release): document subject local-agent smoke"Task 7: Final Verification And Integration
Files:
No new source files beyond previous tasks.
[ ] Step 1: Run focused unit tests
Run:
uv run python -m unittest tests.test_subject_runtime_smoke tests.test_mcp_tool_handlersExpected: all focused tests pass.
- [ ] Step 2: Run full subject runtime verification
Run:
uv run python -m unittest tests.test_subject_guidance tests.test_subject_lifecycle tests.test_guidance_runtime tests.test_subject_runtime_smoke tests.test_subject_refinement tests.test_subject_router_evalExpected: all selected subject runtime tests pass.
- [ ] Step 3: Run preview smoke and router eval
Run:
uv run python tooling/scripts/run_subject_runtime_smoke.py --json
uv run python tooling/scripts/evaluate_subject_router.py --jsonExpected: preview smoke exits 0 with all cases passing; router eval exits 0 with no threshold failures.
- [ ] Step 4: Verify local-agent guard failure remains machine-readable
Run without the environment variable:
uv run python tooling/scripts/run_subject_runtime_smoke.py --mode local-agent --jsonExpected: command exits non-zero and prints JSON with:
{
"schema_version": "1.1",
"mode": "local-agent",
"summary": {"total": 0, "passed": 0, "failed": 1},
"error": "local-agent smoke requires QIONGLI_SMOKE_RUN_AGENTS=1 and launches local runtime agents"
}The JSON should also contain a rerun_command including QIONGLI_SMOKE_RUN_AGENTS=1.
- [ ] Step 5: Optionally run real local-agent smoke when local runtime is available
Run only when the maintainer environment has the selected local runtime configured:
QIONGLI_SMOKE_RUN_AGENTS=1 \
uv run python tooling/scripts/run_subject_runtime_smoke.py \
--mode local-agent \
--case confirmed_finance_guidance_loaded \
--jsonExpected if local runtime is available: command exits 0, summary.failed == 0, local_agent.will_launch_agents == true, trace_assertions.trace_written == true, and write_boundary.known_paths_inside_project == true.
Expected if local runtime is unavailable: command exits non-zero with a failed case that includes runtime preflight or execution diagnostics. Do not treat an unavailable local runtime as a blocker for merging this implementation unless the failure is caused by Qiongli smoke runner logic.
- [ ] Step 6: Run whitespace check
Run:
git diff --checkExpected: exits 0.
- [ ] Step 7: Final status check
Run:
git status --short --branch
git log --oneline --max-count=8Expected: implementation branch is clean after all commits. Recent commits show the task-by-task smoke hardening work.
Self-Review Checklist
- Spec coverage:
- Opt-in local-agent smoke double gate: Task 1, Task 7.
- Bounded real-run arguments: Task 2, Task 3.
- Loaded subject guidance assertions: Task 4.
- Local guidance trace assertions: Task 4.
- Write-boundary checks: Task 5.
- Rerun diagnostics: Task 5.
- Preview smoke remains default: Task 1, Task 7.
- Release-readiness documentation: Task 6.
- Open-item scan:
- No unresolved markers or open-ended edge-case instructions.
- Type consistency:
- Smoke report schema uses
schema_version: "1.1". - Local-agent env var remains
QIONGLI_SMOKE_RUN_AGENTS. - Subject guidance source remains
.qiongli/guidance.d/subject-runtime.md. - MCP bounded args use
max_revision_rounds,output_budget, andskip_validation.
- Smoke report schema uses