Finding
Draft #248 introduces PostgresValidityStudyReadPort as @dataclass(frozen=True, slots=True) and validates connection_factory only in __post_init__. That blocks ordinary assignment but does not provide structural immutability: object.__setattr__(port, "connection_factory", replacement) can replace the dependency after constructor validation.
The adapter already snapshots tenant/study UUID authority before executable connection acquisition. Its dependency authority should meet the same checked-versus-used standard: the connection capability accepted when the port is built must not be replaceable later through a retained port reference.
RED acceptance
Add a focused regression that constructs a port with one valid factory, attempts object.__setattr__ replacement with a second factory, requires AttributeError, and proves the original factory remains the one used by a read.
Minimal repair boundary
Use a structurally immutable representation for the port’s accepted connection dependency while preserving the public PostgresValidityStudyReadPort(connection_factory=...) construction shape, read-only transaction behavior, schema-qualified SQL, tenant RLS binding, bounded fetch, exact row reconstruction, and #247 migration/ACL contract. Do not adopt mutable #235 source into #248, weaken gates, or rewrite history.
Keep this issue open through post-parent non-force adoption, exact-head hosted acceptance and protected integration. Source repair alone is not a close condition.
Finding
Draft #248 introduces
PostgresValidityStudyReadPortas@dataclass(frozen=True, slots=True)and validatesconnection_factoryonly in__post_init__. That blocks ordinary assignment but does not provide structural immutability:object.__setattr__(port, "connection_factory", replacement)can replace the dependency after constructor validation.The adapter already snapshots tenant/study UUID authority before executable connection acquisition. Its dependency authority should meet the same checked-versus-used standard: the connection capability accepted when the port is built must not be replaceable later through a retained port reference.
RED acceptance
Add a focused regression that constructs a port with one valid factory, attempts
object.__setattr__replacement with a second factory, requiresAttributeError, and proves the original factory remains the one used by a read.Minimal repair boundary
Use a structurally immutable representation for the port’s accepted connection dependency while preserving the public
PostgresValidityStudyReadPort(connection_factory=...)construction shape, read-only transaction behavior, schema-qualified SQL, tenant RLS binding, bounded fetch, exact row reconstruction, and #247 migration/ACL contract. Do not adopt mutable #235 source into #248, weaken gates, or rewrite history.Keep this issue open through post-parent non-force adoption, exact-head hosted acceptance and protected integration. Source repair alone is not a close condition.