GOC-44 dependency/runtime compatibility — baseline revalidation (2026-08-16)¶
CONCEPT:AU-ECO.mcp.protocol-compat-bridge
Lane: plans/graph-os-completion-program/lanes/GOC-44-dependency-runtime-compatibility.md
(OWNER-DEPENDENCY-GREEN). This is the GOC-44-W01 output: a timestamped revalidation
of the lane's 13 imported AU–EG IDs against main as it stood on 2026-08-16
(agent-utilities HEAD b60e5b439, worktree
/home/app/.local/state/repository-worktrees/agent-utilities/goc-44,
branch goc/goc-44-dependency-runtime-compat). Every row below records the command
or artifact used to revalidate — no disposition here is inferred from the imported
ledger text alone. Environment: interpreter cpython-3.14.4-linux-x86_64-gnu
(uv-managed, python-build-standalone), host <build-host>
(Linux 7.0.0-28-generic), venv used for live checks:
/home/app/.local/state/repository-worktrees/agent-utilities/goc-87/.venv
(this worktree, goc-44, has no installed venv of its own — see "What is
unverified" below).
Denominator for every count in this document: the 13 IDs imported into
GOC-44's queue (plans/graph-os-completion-program/archive/AU-EG-DEFERRED-IMPORT-LEDGER.md
§"GOC-44 — OWNER-DEPENDENCY-GREEN"), unless a different denominator is stated inline.
Disposition summary¶
| Disposition | Count | IDs |
|---|---|---|
| STALE-PREMISE — already resolved by prior work, evidence attached | 6 | D-HX-1, D-2.1b-2, D-2.1b-3, D-VS-1, D-VS-2, D-W5AGB-1 |
| STALE-PREMISE — self-described transient state, not reproducible today | 1 | D-W2P-7 |
| CONFIRMED-LIVE — already mitigated adequately (fail-closed + tested); no unsafe rush-fix applied | 2 | D-CIP-17, D-CIP-3 |
| CONFIRMED-LIVE — real gap, root cause outside this lane's authority, coordinate with named owner | 2 | D-W6TG-1 (→ GOC-42), D-MQR-4 (partially; → operator) |
| CONFIRMED-LIVE — real gap in this lane's own scope, too large/risky to safely land in one pass; filed as owned blocker | 1 | D-VI-2 |
| DECISION-REQUIRED — operator consolidation call, not a code defect | 1 | D-HX-2 |
No code fix was made in this pass. Every item that looked fixable turned out to already be fixed (dated 2026-07-30 through 2026-08-14, all before this lane's 2026-08-16 revalidation), and every item that is still genuinely open either has an adequate existing mitigation or needs authority/effort this lane cannot safely supply in one pass without full-gate access (which this lane does not run itself — see the program's standing rule 3). This is treated as a legitimate outcome, not a gap: a well-evidenced revalidation is the deliverable this pass, not a forced patch.
Per-ID revalidation¶
D-HX-1 — STALE-PREMISE (resolved)¶
"httpx.AsyncClient handed to mcp.client.streamable_http.streamable_http_client (http_client=...) where httpx2.AsyncClient is typed/expected"
The type mismatch is real and current: mcp==2.0.0's
streamable_http_client(*, http_client: httpx2.AsyncClient | None = None, ...)
is typed against httpx2, and agent_utilities/mcp/multiplexer.py's non-SSE
remote-child branch (around line 2055-2057) builds http_client via
agent_utilities.core.http_client.create_async_http_client, which is httpx-based,
then hands it to streamable_http_client(url, http_client=http_client).
But the runtime claim — that this crossing is broken — does not reproduce. Two independent proofs:
- A dedicated live regression test already exists and already passes:
tests/integration/mcp/test_multiplexer_remote_transport_live.py::test_hardened_client_round_trips_sdk_v2_streamable_http, landed 2026-07-30 (git log, commit5be9443420102b294146fdeb7cebb9c6cfc70151,fix(mcp): repair the MCP SDK v2 breakage the fastmcp-4 default exposed) — i.e. before the AU-EG import even recorded this asOPEN. It callscreate_async_http_client(..., pin_egress=True, ...)— the exact hardened construction multiplexer.py uses — and hands it tostreamable_http_client, completinginitialize+list_tools+call_toolagainst a live fastmcp-4 server. Re-run today: PASSED (goc-87/.venv,pytest tests/integration/mcp/test_multiplexer_remote_transport_live.py -v→1 passed in 33.22s). - An independent probe built for this revalidation
(
/tmp/.../scratchpad/goc44_dhx1_probe.py, not committed — throwaway) drove the same call shape with a barehttpx.AsyncClient(no au hardening) against an in-process FastMCP/uvicorn server and got the same result:PROBE RESULT: OK ['ping'] [TextContent(...text='pong'...)].
httpx and httpx2 are structurally identical forks (documented in
agent_utilities/mcp/httpx_boundary.py); mcp.client.streamable_http never does
an isinstance check against http_client itself — it only calls duck-typed
methods (.stream(), .build_request(), .send(), .aclose()), and even
httpx2.EventSource(response) (constructed from an httpx.Response, not
httpx2.Response, in the SSE fallback path) iterates correctly, checked directly
against httpx2.EventSource. The mismatch is a real static-typing fact with a
committed, currently-passing runtime proof it doesn't matter here. No fix
applied; the existing test is the fix's evidence. Coordination note: the ledger
names GOC-26 as the coordinating lane for this ID; this finding should be shared
with GOC-26 rather than re-litigated there.
D-HX-2 — DECISION-REQUIRED (unchanged, not this lane's call)¶
"Root cause of the httpx/httpx2 duality: deliberate early fastmcp>=4.0.0b1 adoption, not vendoring/accident -- operator decision needed on consolidation path"
Confirmed accurate and still pending. pyproject.toml's [tool.uv]
override-dependencies comment (fastmcp-slim[client,server]>=4.0.0b1) documents
the same root cause in the same terms. GOC-87 has since landed the sanctioned
interim mitigation while that decision remains open: a staged transport-factory
seam (agent_utilities/httpsupport/transport_factory.py,
docs/architecture/httpx_httpx2_migration.md) that lets call families migrate to
httpx2 one at a time, checked, rather than either a wholesale swap or an
indefinite freeze. As of the 2026-08-16 lock referenced in that doc: 17 locked
packages require httpx, 3 require httpx2; 48 files import httpx, 2 import
httpx2 (denominator: files under agent_utilities/, per that doc). A repo-wide
grep run for this revalidation (denominator: all tracked .py files, a superset
including tests/) found 52 files importing httpx and 4 importing httpx2 —
consistent with that count once test files are included. No action for this
lane beyond recording that the interim mitigation exists and the consolidation
decision itself remains genuinely unmade; it is an operator call, not a
revalidation outcome.
D-VI-2 — CONFIRMED-LIVE, filed as owned blocker (not fixed this pass)¶
"Unrecognized uv flags degrade to uv's own sync behaviour"
Confirmed still true by reading scripts/uv_workspace.py::main/uv_plan
directly: the CLI parser uses nargs=argparse.REMAINDER (line ~1810) and every
subcommand branch splices the remainder straight through to the real uv binary
(*tail for sync/lock, command.extend(tail) for run, [*base, *arguments]
for anything else) with no allow-list or validation layer. A flag uv itself
doesn't recognize will fail via uv's own error (that much is fail-closed), but a
flag uv does recognize and that changes sync/lock semantics in a way this
wrapper's environment-partitioning, UV_PROJECT_ENVIRONMENT pinning, or
pool-gated-heavy-sync assumptions (_dependency_sync_slot()) don't account for
will pass straight through and "degrade to uv's own [unpartitioned] sync
behaviour" exactly as the imported title says — this is a real, reproducible gap
against the lane's own authority ("Unsupported uv flags... fail closed with the
exact command and supported alternative; no unknown-flag pass-through is
accepted").
Not fixed in this pass. A safe fix requires enumerating uv's actual flag
surface per subcommand (sync/lock/run/others) and classifying each as
safe-to-passthrough vs. wrapper-assumption-breaking — this wrapper is used by
every lane's uv-lock pre-commit hook and pool-gates real dependency downloads
fleet-wide (per the workspace CLAUDE.md GOC context and this repo's own
git-hook ambient env breaks ls-files-class incident history), so an incomplete
allow-list risks a false-positive rejection that blocks every lane's commits —
exactly the failure mode gates-report-more-coverage-than-they-have warns
against. This is properly GOC-44-W02/W03 scope (candidate/compatibility contract
definition, flag/interpreter parity) rather than a same-pass patch. Filed as an
owned blocker: needs a dedicated audit of uv sync|lock|run's flag surface
before an allow-list can be written and tested without full-gate access.
D-VS-1 / D-VS-2 — STALE-PREMISE (resolved by an ecosystem architecture change)¶
D-VS-1: "★★ ENDGAME: make the bare
uv synccorrect via a two-line root-manifest change" D-VS-2: "Nothing intercepts a human or agent typinguv syncdirectly"
Both resolved — not by intercepting bare uv sync, but by removing the shared
[tool.uv.workspace] root that made a bare sync's behavior depend on sibling
repos in the first place. /home/app/workspace/pyproject.toml (the former
ecosystem workspace root) now carries an explicit D-EGSFT-1 header dated
2026-08-14 ("owner-approved architecture change"): it is "intentionally NOT a
[tool.uv.workspace] root anymore." Every repo (69/69 agents/* + agent-utilities
+ epistemic-graph + agent-webui + geniusbot + langfuse-agent +
leanix-agent, per that file's own verification note) now resolves and locks
independently against its own uv.lock, so a bare uv sync run inside any one
repo resolves that repo's own lock — the correct behavior — rather than being
pulled into a shared workspace-wide resolve. The former workspace-root-only [tool.uv]
override-dependencies (nltk/pytest/cryptography/opentelemetry/fastmcp-slim
floors) were redistributed into each repo that needs them (checked for
fastmcp-slim above under D-2.1b-2).
Caveat, not a fix needed by this lane: agent-utilities/pyproject.toml
still carries a "Known residual limitation" comment (lines ~844-857) about bare
uv sync from the canonical checkout (not a worktree) hitting a
per-member-name-collision when it discovers the outer ecosystem workspace as an
ancestor — but that comment is dated 2026-08-13 (git log -L), one day
before D-EGSFT-1 removed the outer [tool.uv.workspace] table entirely. Since
the collision rule this comment describes only fires when uv discovers an
ancestor workspace, and there is no longer one to discover, this documentation is
now very likely stale itself. Not checked empirically in this pass (will
require running bare uv sync inside the canonical
agent-packages/agent-utilities checkout, which this lane's own instructions
prohibit editing/running heavy operations against). Flagged for whoever next
touches that comment to confirm and prune if stale.
D-W5AGB-1 — STALE-PREMISE (resolved 2026-08-07, before this lane existed)¶
"Ecosystem-wide uv.lock has a deliberate cryptography<49 override (mlflow/data-science-mcp) that directly contradicts agent-utilities' CVE-driven >=50.0.0 floor"
Resolved. agent-packages/agents/data-science-mcp/pyproject.toml carries a
dated comment (2026-08-07 (D-W5AGB-1)) explaining that mlflow — the sole
source of the cryptography<49 requirement — was removed from that package's
optional dependencies specifically because no published mlflow release (as of
that date, including the-then-latest 3.15.1) supports cryptography>=50.0.0
(the fix for PYSEC-2026-3552). Checked for this revalidation: grep -n
"mlflow" agents/data-science-mcp/pyproject.toml shows only comment lines (the
historical explanation and reinstatement condition), no active dependency
declaration; grep -rln "cryptography<49" across agent-packages/*/pyproject.toml
and agent-packages/agents/*/pyproject.toml (denominator: 1 + 68 files) returns
only that same commented-out file. agent-utilities/pyproject.toml's own floor
("cryptography>=50.0.0", line 56) is unchanged and uncontested.
D-2.1b-2 — STALE-PREMISE (resolved, fully checked)¶
"Downstream
agents/*packages need the samefastmcp-slim[client,server]override"
Resolved and checked with a full-population check, not a sample. Denominator:
69 directories under agent-packages/agents/ (68 with a pyproject.toml; the
69th is tests/, which has none). Of the 68, all 68 mention fastmcp and all
68 already carry "fastmcp-slim[client,server]>=4.0.0b1" in their own
[tool.uv] override-dependencies (grep -l "fastmcp-slim\[client,server\]"
*/pyproject.toml → 68/68). 0 of 68 are missing the override.
D-2.1b-3 — STALE-PREMISE (resolved, live-tested)¶
"
tests/integration/not re-run under fastmcp 4 (onlytests/unit/mcp/+ the rewritten live-path tests)"
Resolved. tests/integration/ contains 81 test files, 16 of which reference
fastmcp/mcp. (denominator: files under tests/integration/, grep -rl).
A dedicated fastmcp-4 live-server integration test exists —
tests/integration/mcp/test_fastmcp_cross_version.py — whose own docstring
states it replaces the prior dual-extra fastmcp-3-vs-4 cross-version guard
because fastmcp 4 is now au's single default; it drives
agent_utilities.mcp.toolset_factory.build_stdio_toolset (au's actual
production call path) against a real fastmcp-4 stdio server end-to-end. Re-run
today: PASSED (goc-87/.venv, pytest
tests/integration/mcp/test_fastmcp_cross_version.py -v → 1 passed, 4 warnings
in 23.47s; warnings are pydantic-ai DeprecationWarnings about MCP SDK v2
field renames, unrelated to this ID). Git history for tests/integration/
(git log --oneline -5) shows recent, active maintenance (fix(tests): resolve
the long tail of single-test failures, etc.), not an abandoned suite.
D-W2P-7 — STALE-PREMISE (self-described transient state)¶
"guardrail-surface-parity / guardrail-cpd-drift / 1 gate-meta-test: worktree .venv not yet synced (contended, not a code defect)"
The imported title self-classifies this as not a code defect — a point-in-time
contention state in one worktree (w2-precommit-0802.md) that no longer exists.
Not independently reproducible today; no corresponding worktree or contention
state exists in the current environment. No action needed; recorded as
STALE-PREMISE per its own original disposition, not a new finding.
D-CIP-17 — CONFIRMED-LIVE, already adequately mitigated¶
"uv-managed CPython (python-build-standalone) lacks os.memfd_create -- promote_local_release tests fail under the project's own sanctioned local test runner"
The capability gap itself is confirmed, live, on the current interpreter:
python3 -c "import os; print('memfd_create' in dir(os))" under
/home/app/.local/share/uv/python/cpython-3.14.4-linux-x86_64-gnu/bin/python3.14
prints False, even though the same host/kernel's distro interpreter has it
(this is a python-build-standalone build artifact, not a real platform
limitation — the host is Linux 7.0.0-28, which supports the syscall).
This is already mitigated to the standard this lane's authority requires,
not left silently degraded: scripts/release/promote_local_release.py's
_require_supported_platform() explicitly checks
hasattr(os, "memfd_create") (and the matching fcntl seal constants) and
raises ReleaseError("unsupported-platform") — a typed, fail-closed refusal,
not a crash or silent skip. tests/unit/release/test_promote_local_release.py
documents the exact root cause in two places (HAVE_MEMFD_CREATE=0 under uv's
pinned CPython 3.14.4, contrasted with the distro interpreter on the same
host/kernel) and deliberately monkeypatches around the irrelevant precondition
in tests that aren't about platform support, while a dedicated test
(test_native_promoter_rejects_unsupported_platform, referenced by name in
those comments) covers the fail-closed gate itself. No fix applied — the
existing gate and tests already meet the bar. The residual fact that
promote_local_release's real signing flow cannot run end-to-end under
the sanctioned uv-managed interpreter on this host is a genuine operational
constraint (needs either a memfd_create-capable interpreter build or an
alternate sealed-fd primitive), not a design defect, and is outside a single
revalidation pass to resolve.
D-CIP-3 — CONFIRMED-LIVE at the PyPI level, already worked around¶
"epistemic-graph[full]>=2.23.2 is unsatisfiable from PyPI (max published 2.23.0)"
Confirmed still numerically true: curl -s
https://pypi.org/pypi/epistemic-graph/json → latest published 2.23.0;
pyproject.toml line 144 requires "epistemic-graph[full]>=2.23.2,<3.0.0".
But no live workflow actually resolves this against bare PyPI.
[tool.uv.sources] (pyproject.toml line 858) overrides epistemic-graph to
a local editable path (.uv-workspace-siblings/epistemic-graph) — materialized
by scripts/uv_workspace.py's materialize_own_siblings for local/lane use and
by .github/workflows/security.yml's actions/checkout for the one CI job that
needs the real package; every other CI workflow instead excludes the package
entirely (--no-install-package epistemic-graph --no-install-package
langfuse-agent, per the same comment block). So the unsatisfiable-from-PyPI
fact is real, but every actual resolution path either bypasses PyPI for this
package or excludes it — there is no reproducible failure to fix here. The root
fix (publish epistemic-graph>=2.23.2 to PyPI) is GOC-31's territory per the
ledger's own coordination column, consistent with the wider "PyPI publish gate
never runs" finding GOC-42 already made for agent-utilities itself (see
D-W6TG-1 below for the same pattern hitting a downstream consumer).
D-MQR-4 — CONFIRMED-LIVE (version divergence), partially unverified¶
"Reinstall repository_manager editable against python3.14 and reconcile 1.3.53-vs-3.0.0 version divergence"
The version-divergence half is confirmed and, if anything, larger than the
imported title states: agent-packages/agents/repository-manager/pyproject.toml
declares local version = "3.4.0"; PyPI's published repository-manager is
2.0.1 (curl -s https://pypi.org/pypi/repository-manager/json). This is the
same class of finding already recorded in the operator's own memory
(gate-tool-published-before-gate-adopted.md: "PyPI had 2.0.1... local shipped
3.4.0"), so this is a known, tracked, still-open condition, not a new
regression — this revalidation independently reconfirms the same numbers.
requires-python = ">=3.12,<3.15" in that pyproject.toml covers 3.14, so the
python3.14 compatibility declaration is fine on its face.
Unverified in this pass: whether repository_manager is actually
installed editable against a python3.14 interpreter anywhere it needs to run
(the mission-relevant half of the imported title). No editable install of
repository_manager was found in the one venv inspected
(goc-87/.venv, pip show repository-manager → module not present, and that
venv has no pip at all) — but that venv is agent-utilities' own, not
repository-manager's, so its absence there is not evidence either way. This
lane did not locate or inspect wherever repository-manager's own editable
install actually lives operationally (its own worktree/venv, or the graph-os
container). Left unverified rather than guessed at.
D-W6TG-1 — CONFIRMED-LIVE, root cause outside this lane, coordinate with GOC-42¶
"geniusbot Build workflow red on origin/main: requirements.txt/pyproject.toml require agent-utilities>=2.0.0, unpublished on PyPI (== D-W2PU-1 root cause)"
Confirmed still live, and slightly worse than the title states once both of
geniusbot's dependency declarations are checked, not just one:
- PyPI agent-utilities latest published is 1.26.4
(curl -s https://pypi.org/pypi/agent-utilities/json) — consistent with
GOC-42's prior finding cited in this lane's own briefing.
- agent-packages/geniusbot/pyproject.toml line 27 requires
"agent-utilities>=2.0.0" — unsatisfiable from PyPI alone, exactly as the
imported title says. It is worked around the same way as D-CIP-3 above: a
[tool.uv.sources] local editable-path override (line 85) resolves it via
.uv-workspace-siblings/agent-utilities for uv-based workflows.
- agent-packages/geniusbot/requirements.txt line 7 pins
agent-utilities==1.0.0 — a third, even more stale expectation, and one the
[tool.uv.sources] override cannot reach at all (plain pip install -r
requirements.txt resolves straight against PyPI). Any CI job that installs
from requirements.txt rather than through uv sees a target that is
neither what pyproject.toml wants (>=2.0.0) nor what PyPI actually has
latest (1.26.4).
This is the same root cause GOC-42 already identified for agent-utilities
itself ("PyPI agent-utilities is capped at 1.26.4 while local is far ahead");
D-W6TG-1 is that same root cause surfacing in a downstream consumer's CI. The
fix is a real PyPI publish of agent-utilities>=2.0.0, which is GOC-42's
release-authority territory and outside this lane's non-goals (no publication
without explicit authorization). Recommendation only, not applied:
geniusbot/requirements.txt's agent-utilities==1.0.0 pin is also
inconsistent with geniusbot/pyproject.toml's own >=2.0.0 floor in either case
of the publish gap, and independent of the PyPI-publish fix — that file is
outside this lane's owned-repository list (geniusbot is not agent-utilities,
agents/*, or repository-manager) and was left untouched.
What is unverified¶
- The "Known residual limitation" comment in
agent-utilities/pyproject.toml(bareuv syncfrom the canonical checkout) was not empirically re-tested against the post-D-EGSFT-1 (2026-08-14) architecture — this lane's instructions prohibit running heavy operations against the canonical checkout, and this worktree (goc-44) has no venv of its own to test with in isolation either. - D-MQR-4's
repository_managereditable-install-against-python3.14 claim: this lane did not locate where that install actually runs operationally. - D-VI-2's full
uvflag surface was not enumerated; only the wrapper's own passthrough behavior was confirmed by code reading, not exhaustive testing against every realuvflag. - No new code was authored or changed in
agent_utilities/in this pass; the two live tests cited (test_multiplexer_remote_transport_live.py,test_fastmcp_cross_version.py) were re-run, not modified.