Skip to content

fix(workforce-validation): reject inherited Protocol repository placeholders before authorization #253

Description

@seonghobae

Finding

Fresh exact-head review of Draft #235 at db7ce6b117052ea4fba59e61f15fd22389abe194 found that the pre-authorization repository-capability gate accepted an inherited ValidityStudyReadPort.read_validity_study Protocol stub as though it were a concrete owner repository implementation.

A concrete class can inherit ValidityStudyReadPort without overriding read_validity_study. inspect.getattr_static(type(read_port), "read_validity_study", None) then resolves the inherited Protocol function, whose runtime type is still FunctionType, so the old gate passed. Purpose-bound Keyverse evaluation therefore occurred before the boundary discovered that no concrete repository implementation existed.

This is a dependency-integrity finding adjacent to #249, not a replacement for it. #249 binds the exact validated function to post-authorization invocation; #253 requires that the function accepted by that binding be a concrete implementation rather than the Protocol declaration itself.

Test-first repair

Test-only 14c10e8fe4861299ab4808d2e25cf25df35c8549 adds _InheritedProtocolReadPort(ValidityStudyReadPort) with no override and supplies a deliberately non-matching purpose policy. The required behavior is TypeError from dependency validation before Keyverse can evaluate that policy. On the predecessor implementation the inherited Protocol function passes the FunctionType gate, so this is a causal RED contract. The test-only head was immediately followed by the production successor; no hosted RED is claimed.

Production 72ec2296cbc6b2df94e9c4e7394a8990061d0c88 stores the canonical Protocol declaration with inert getattr_static(...) and rejects a captured repository function when it is either not an exact FunctionType or identity-equal to that Protocol declaration. The existing error contract is preserved. Ordinary concrete class methods continue through #249's exact capture-and-direct-invocation path without a second dynamic lookup.

db7ce6b... → 72ec2296... is ordinary ahead-only history: two commits, zero behind, and only registry.py plus the focused dependency-integrity regression changed. No SQL, migration, Keyverse adapter, Foundation workflow, manifest, child #248 source, or baseline writer file changed.

Exact-head review and remaining acceptance

CodeRabbit has now reviewed exact 72ec2296cbc6b2df94e9c4e7394a8990061d0c88 against protected develop@eb9757f8649aaad026a9865508d9aad50c1a7a4f and found no blocking defect in the requested #253/#249 static scope. It verified that 14c10e8... is the direct test-first parent, that the concrete inherited-Protocol regression would reach a deliberately denying policy on the predecessor, that the production repair rejects the canonical Protocol declaration before Keyverse evaluation, and that ordinary concrete repository methods preserve #249's exact captured-function invocation without a second dynamic lookup.

This is static exact-head evidence only. Current #235 workflows remain Foundation 33974101917, Security 33974101943, SAST 33974101951, and CodeQL 33974102004, all pending/queued at the latest read. Formal reviews are COMMENTED-only; no qualifying APPROVED review exists. Keep #253 open through current-head hosted acceptance and normal protected integration. A source fix or static review alone is not a close condition. No self-approval, admin bypass, gate weakening, force-push, mutable sibling source copy, or predecessor-evidence transfer.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions