Skip to content

[codex] Harden adapter layer: dedup helpers, reuse isolation, coverage gate - #24

Merged
ebarti merged 3 commits into
codex/codex-process-reusefrom
codex/adapter-hardening
Jul 2, 2026
Merged

ebarti merged 3 commits into
codex/codex-process-reusefrom
codex/adapter-hardening

Conversation

@ebarti

@ebarti ebarti commented Jun 30, 2026

Copy link
Copy Markdown
Owner

Stacked on #23 (codex/codex-process-reuse). Addresses the adapter-layer review findings on top of the SDK process-reuse work.

What this does

Refactor — kill the cross-adapter duplication

The three vendor adapters had copy-pasted helpers that drifted (and previously produced three identical bugs). Consolidated into adapters/_common.py:

  • field_value, optional_int, optional_str
  • fingerprint_value / fingerprint_item (single superset incl. the pydantic model_dump branch)
  • close_vendor_resource(primary, *, fallback=, try_disconnect=) — one close ladder for all three

Fixes

  • Claude reuse isolation: the reuse cache key is now scoped by conversation identity (resume_from/session_id), so two tasks with distinct sessions never share one client even with identical options. No-session tasks still share the process (isolated by per-query session id). New AgentResult.metadata["sdk_process_reuse_scope"] ("conversation" / "shared").
  • Antigravity chmod crash: _runtime_dir only enforces 0o700 on dirs we own and tolerates (logs, does not crash) a chmod failure on a shared / non-owned data_dir.
  • Observable cleanup: a failure while closing a vendor resource after a startup failure is now logged (logging.warning) instead of being silently suppressed. The original startup error still propagates.

Tests

  • New tests/test_adapter_protocol.py: one parametrized AgentRuntime conformance suite across all three adapters (protocol membership, async lifecycle, availability diagnostic, ordered task lifecycle events).
  • Regressions: Claude session-scoped reuse (shared vs conversation), chmod-failure survival, per-adapter close-failure warnings, and safe_emit resilience (exploding sink must not abort a run).

Coverage gate + docs

  • pytest-cov + --cov-fail-under=85 in CI (current ~89%); real-SDK _load_sdk imports marked # pragma: no cover (unreachable in the SDK-free CI lanes).
  • docs/providers.md: documents the session-scoped reuse key, sdk_process_reuse_scope, and that reuse_process=True serializes runs on a runtime instance.

Verification

  • uv run ruff check . — clean
  • uv run mypy — clean (14 files)
  • uv run pytest -q --cov=agent_runtime_kit --cov-fail-under=85 — 154 passed, 3 skipped, coverage 88.94%

Default per-call isolation behavior is unchanged.

ebarti added 3 commits July 1, 2026 01:09
Consolidate the helpers that had been copy-pasted across the three vendor
adapters into adapters/_common.py (field_value, optional_int, optional_str,
fingerprint_value/fingerprint_item, and a single close_vendor_resource ladder),
removing the per-adapter drift that previously produced three identical bugs.

Also harden the reuse path:
- Claude: scope the reuse cache key by conversation identity so tasks with
  distinct sessions never share one client; expose sdk_process_reuse_scope.
- Antigravity: only chmod the runtime dir when we own it, and tolerate (log,
  not crash) a chmod failure on a shared/non-owned data dir.
- All adapters: log a warning when closing a vendor resource fails after a
  startup failure instead of silently suppressing it.
Add tests/test_adapter_protocol.py parametrizing all three adapters through one
AgentRuntime conformance suite (protocol membership, async lifecycle methods,
availability diagnostic, ordered task lifecycle events).

Regression coverage for the hardening:
- Claude reuse keyed by session (shared vs conversation scope) and a close-
  failure-after-connect-failure warning path.
- Antigravity runtime dir survives a chmod PermissionError; close-failure
  warning after enter failure.
- Codex close-failure warning after enter failure.
- safe_emit: an exploding event sink must not abort a run.
- Add pytest-cov dev dependency, [tool.coverage] config, and a
  --cov-fail-under=85 gate in CI (current coverage ~89%). Mark the real-SDK
  import bodies in each _load_sdk with pragma: no cover (unreachable in the
  SDK-free CI lanes).
- docs/providers.md: document Claude's session-scoped reuse key and
  sdk_process_reuse_scope, and that reuse_process=True serializes runs on a
  runtime instance.
@ebarti
ebarti merged commit 6264fc7 into codex/codex-process-reuse Jul 2, 2026
8 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