Finding
PR #235 currently validates read_port.read_validity_study before purpose-bound authorization with inspect.getattr_static(...), but later invokes the dependency through a fresh dynamic attribute lookup (read_port.read_validity_study(...)). Those are not necessarily the same capability.
A caller-controlled repository object can expose a safe ordinary class method to static inspection while overriding instance __getattribute__ so the post-authorization lookup returns a different executable callable. In that case the dependency that passed the inert pre-authorization check is not the dependency actually used after authorization. This is a checked-versus-used trust-boundary defect, complementary to #240 rather than a duplicate of it.
RED acceptance
Add a focused regression whose port has:
- one ordinary class-level
read_validity_study method that static inspection can validate;
- an instance
__getattribute__ trap that returns a different callable for dynamic read_validity_study lookup;
- a valid purpose-bound request/policy.
The authorized read must invoke exactly the statically validated ordinary method and must never execute the dynamic lookup trap.
Minimal repair boundary
Bind one exact inert repository method before authorization, require the supported ordinary instance-method shape, and invoke that same validated function directly after authorization with the port receiver. Do not perform a second dynamic capability lookup after authorization. Preserve #239–#245 principal/policy/UUID/target/view invariants, field minimization, owner-port contract, Foundation gates, and the independent #248 persistence child.
Keep this issue open through exact-head hosted acceptance and normal protected integration. A source fix alone is not a close condition. No self-approval, admin bypass, gate weakening, force-push, mutable sibling source copy, or predecessor evidence transfer.
Finding
PR #235 currently validates
read_port.read_validity_studybefore purpose-bound authorization withinspect.getattr_static(...), but later invokes the dependency through a fresh dynamic attribute lookup (read_port.read_validity_study(...)). Those are not necessarily the same capability.A caller-controlled repository object can expose a safe ordinary class method to static inspection while overriding instance
__getattribute__so the post-authorization lookup returns a different executable callable. In that case the dependency that passed the inert pre-authorization check is not the dependency actually used after authorization. This is a checked-versus-used trust-boundary defect, complementary to #240 rather than a duplicate of it.RED acceptance
Add a focused regression whose port has:
read_validity_studymethod that static inspection can validate;__getattribute__trap that returns a different callable for dynamicread_validity_studylookup;The authorized read must invoke exactly the statically validated ordinary method and must never execute the dynamic lookup trap.
Minimal repair boundary
Bind one exact inert repository method before authorization, require the supported ordinary instance-method shape, and invoke that same validated function directly after authorization with the port receiver. Do not perform a second dynamic capability lookup after authorization. Preserve #239–#245 principal/policy/UUID/target/view invariants, field minimization, owner-port contract, Foundation gates, and the independent #248 persistence child.
Keep this issue open through exact-head hosted acceptance and normal protected integration. A source fix alone is not a close condition. No self-approval, admin bypass, gate weakening, force-push, mutable sibling source copy, or predecessor evidence transfer.