Skip to content
Draft
49 changes: 30 additions & 19 deletions docs/research/connection-pool-resource-limits.md
Original file line number Diff line number Diff line change
Expand Up @@ -18,13 +18,18 @@ an exact `EgressConnectionPoolPolicy` with different documented field values
instead. This boundary does not claim EgressWeave sandboxes arbitrary Python
code already executing inside the embedding process.

`max_connections` must be a positive integer or ASCII decimal string.
`max_keepalive_connections` may be zero to retain no idle connections but must
not exceed total capacity. `keepalive_expiry_seconds` must be a finite
non-negative real number and may be zero for immediate expiry. Booleans,
fractional counts, signed or non-ASCII count text, negative values, non-finite
expiry values, unrelated objects, and contradictory capacities fail during
trusted policy construction.
`max_connections` must be an exact built-in `int` greater than zero or an exact
built-in `str` containing only ASCII decimal digits.
`max_keepalive_connections` accepts the same reviewed forms, may be zero to
retain no idle connections, and must not exceed total capacity. Integer and
string subclasses are rejected before normalization so caller-defined numeric
or text-protocol behavior cannot cross the trusted configuration boundary. A
caller using either subclass form must migrate by converting its validated value
to an exact built-in integer or exact ASCII decimal string before constructing
the policy. `keepalive_expiry_seconds` must be a finite non-negative real number
and may be zero for immediate expiry. Booleans, fractional counts, signed or
non-ASCII count text, negative values, non-finite expiry values, unrelated
objects, and contradictory capacities fail during trusted policy construction.

## Standards basis

Expand Down Expand Up @@ -54,18 +59,22 @@ and portable across standalone and modular integrations.
1. Both public `EgressPolicy` constructors accept the same immutable pool policy.
2. Trusted construction accepts only the exact `EgressConnectionPoolPolicy`
type; subclasses are rejected before transport pool values are read.
3. Total connection capacity is always positive and finite.
4. Idle capacity is finite, may be zero, and cannot exceed total capacity.
5. Idle expiry is finite and non-negative; `None` cannot disable reclamation.
6. Synchronous and asynchronous HTTPCore pools receive the exact normalized
3. Count fields accept only exact built-in integers or exact built-in ASCII
decimal strings; integer subclasses, string subclasses, and booleans are
rejected before numeric or text protocol methods are invoked.
4. Total connection capacity is always positive and finite.
5. Idle capacity is finite, may be zero, and cannot exceed total capacity.
6. Idle expiry is finite and non-negative; `None` cannot disable reclamation.
7. Synchronous and asynchronous HTTPCore pools receive the exact normalized
values from the policy.
7. No transport imports HTTPX's private `DEFAULT_LIMITS` object.
8. The normalized pool policy participates in deterministic policy and decision
8. No transport imports HTTPX's private `DEFAULT_LIMITS` object.
9. The normalized pool policy participates in deterministic policy and decision
fingerprints without recording live connection state.
9. Defaults, valid environment-style count text, invalid configuration,
relational invariants, exact policy-type enforcement, sync/async delegation,
public API exposure, and fingerprint drift are covered by offline regression
tests with complete production statement and branch coverage.
10. Defaults, valid environment-style count text, invalid configuration,
relational invariants, exact policy-type and scalar-type enforcement,
sync/async delegation, public API exposure, and fingerprint drift are covered
by offline regression tests with complete production statement and branch
coverage.

## Operational guidance

Expand All @@ -80,8 +89,10 @@ assuming it is universally safer.

Applications that previously subclassed `EgressConnectionPoolPolicy` must
migrate to an exact instance and configure the supported finite fields directly.
The exact-type check runs during trusted startup, before a pool or request can
consume those values.
Applications that supplied integer or string subclasses for either count must
convert the validated count to an exact built-in `int` or exact built-in ASCII
decimal `str`. These exact-type checks run during trusted startup, before a pool
or request can consume those values.

## References

Expand Down
12 changes: 6 additions & 6 deletions src/egressweave/connection_pool_policy.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,9 +22,9 @@ def _normalize_connection_count(
"""Return one exact ASCII-compatible connection-count limit."""
if isinstance(value, bool):
raise TypeError(f"{field_name} must be an integer or ASCII decimal string")
if isinstance(value, int):
if type(value) is int:
normalized = value
elif isinstance(value, str):
elif type(value) is str:
if not value or not value.isascii() or not value.isdecimal():
raise ValueError(f"{field_name} must be an ASCII decimal string")
normalized = int(value, 10)
Expand Down Expand Up @@ -56,10 +56,10 @@ class EgressConnectionPoolPolicy:
``max_connections`` is the maximum number of concurrent TCP connections the
pool may own. ``max_keepalive_connections`` limits the subset retained while
idle and may be zero to disable idle retention. Both count fields accept
exact integers or ASCII decimal strings for environment-derived settings.
``keepalive_expiry_seconds`` limits how long an idle connection remains
reusable and may be zero for immediate expiry. The defaults preserve HTTPX's
documented finite baseline without importing HTTPX's private
exact integers or exact ASCII decimal strings for environment-derived
settings. ``keepalive_expiry_seconds`` limits how long an idle connection
remains reusable and may be zero for immediate expiry. The defaults preserve
HTTPX's documented finite baseline without importing HTTPX's private
``DEFAULT_LIMITS`` object.
"""

Expand Down
24 changes: 24 additions & 0 deletions tests/test_connection_pool_count_value_documentation.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
"""Documentation contracts for exact connection-pool count value types."""

from __future__ import annotations

from pathlib import Path

REPOSITORY_ROOT = Path(__file__).resolve().parents[1]
POOL_GUIDE_PATH = (
REPOSITORY_ROOT / "docs" / "research" / "connection-pool-resource-limits.md"
)


def test_connection_pool_guide_documents_exact_builtin_count_values() -> None:
"""Keep operator guidance aligned with the primitive-value integrity boundary."""
guide = " ".join(POOL_GUIDE_PATH.read_text(encoding="utf-8").split())

for fragment in (
"exact built-in `int`",
"exact built-in `str`",
"Integer and string subclasses are rejected",
"must migrate",
"exact built-in ASCII decimal `str`",
):
assert fragment in guide
63 changes: 63 additions & 0 deletions tests/test_connection_pool_count_value_types.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
"""Security contracts for exact connection-pool count value types."""

from __future__ import annotations

import pytest

from egressweave import EgressConnectionPoolPolicy


class _ConnectionCountSubclass(int):
"""Represent an unreviewed integer subclass crossing trusted configuration."""


class _ExplodingCountString(str):
"""Expose polymorphic string inspection in trusted count normalization."""

def isascii(self) -> bool:
"""Fail if normalization invokes a subclass-controlled text method."""
raise AssertionError("string subclass isascii executed")


@pytest.mark.parametrize(
"field_name",
["max_connections", "max_keepalive_connections"],
)
def test_connection_pool_policy_rejects_integer_subclasses(field_name: str) -> None:
"""Reject non-exact integers before retaining finite pool-capacity values."""
with pytest.raises(TypeError, match=field_name):
EgressConnectionPoolPolicy(
**{field_name: _ConnectionCountSubclass(1)} # type: ignore[arg-type]
)


@pytest.mark.parametrize(
"field_name",
["max_connections", "max_keepalive_connections"],
)
def test_connection_pool_policy_rejects_string_subclasses_before_inspection(
field_name: str,
) -> None:
"""Reject non-exact strings before invoking their text protocol methods."""
with pytest.raises(TypeError, match=field_name):
EgressConnectionPoolPolicy(
**{field_name: _ExplodingCountString("1")} # type: ignore[arg-type]
)


def test_connection_pool_policy_keeps_reviewed_count_input_forms() -> None:
"""Continue accepting exact integers and reviewed ASCII decimal strings."""
exact_integer = EgressConnectionPoolPolicy(
max_connections=8,
max_keepalive_connections=2,
)
decimal_string = EgressConnectionPoolPolicy(
max_connections="8",
max_keepalive_connections="2",
)

assert type(exact_integer.max_connections) is int
assert type(exact_integer.max_keepalive_connections) is int
assert decimal_string == exact_integer
assert type(decimal_string.max_connections) is int
assert type(decimal_string.max_keepalive_connections) is int
Loading