Skip to content

People application must detach validated mutation commands before authorization callbacks #231

Description

@seonghobae

Finding

Canonical owner is #64. At predecessor 62a6b7ac2908dce2ea760c13123f8685a6f0eb5c, generic People application entry points and accept_confirmed_hire(...) exact-validated caller-owned frozen commands, but purpose-bound authorization and the mutation-port call still consumed those same caller objects. #229 detached only result target UUIDs; #230 detached only after direct PostgreSQL port entry.

That left non-result semantics mutable between validation and use. A valid PurposeBoundAccessPolicy.resource_kind may be a runtime str subtype, and policy comparison can execute subclass equality/inequality behavior. A retained command can therefore be rewritten with object.__setattr__ during authorization. Changing Employment person_record_id, Position job_profile_id, Assignment position_record_id, or hire PII such as display_name leaves the primary result identity unchanged, so #229 alone cannot detect the semantic substitution; #230 is too late and alternate ports do not receive it.

Test-first repair

Generic test-only successor f7415084d801bc06be316b022f41f53763197882 adds three application regressions. Valid executable policy comparison rewrites the retained caller command during authorization; acceptance requires Employment, Position, and Assignment ports to receive a distinct command carrying the original validated semantics while the caller object is demonstrably changed.

Follow-up test-only successor 5a6354a94a4098509d68a6d413c0dbe8b236f94f adds the symmetric confirmed-hire regression: authorization comparison rewrites retained display_name, but HireAcceptancePort must receive a distinct command preserving the original PII and authoritative identities.

Both test-only heads were immediately superseded and their Foundation/Security/SAST/CodeQL runs were cancelled. Hosted RED is therefore not claimed; predecessor control flow is the causal RED.

Production repair

Generic production e4d538c3e5c0707b650e4eeefb7d91dc4611fe9e imports dataclasses.replace in mutations.py and creates a fresh exact command immediately after each exact outer-type gate. Current 9771be6d65bef77408cd5ad1ae316f0a8d8fb5e3 applies the same rule in hire.py. Expected-result snapshots, purpose-bound authorization, and mutation-port calls use only the detached command.

From #229 head 62a6b7ac… to current 9771be6… the branch is four ordinary commits ahead / zero behind. Net #231 scope is two production files (mutations.py +4/-4, hire.py +2/-2) and two regression files. SQL, schema, transaction boundaries, HR domain semantics, Keyverse authorization-owner source, #229 result-target validation, and #230 direct-PostgreSQL detachment remain unchanged.

Current acceptance

Fresh CodeRabbit static review of exact 9771be6d65bef77408cd5ad1ae316f0a8d8fb5e3 against protected develop@eb9757f… found no defect in #231. It verified exact-type gate → replace(command) → pre-port target capture/authorization → detached-command-only port call for all four application services, confirmed #229 pre-port result authority and #230 adapter detachment remain intact, found both regression modules cover the intended boundaries, and reported git diff --check clean. It explicitly did not transfer predecessor evidence. Its helper script had one commit-parent-printing omission, so ancestry is supported separately by connector compare evidence rather than inferred from that review.

Exact-current workflows are Foundation 33943808189, Security 33943808260, SAST 33943808200, and CodeQL PR 33943808117. Foundation job 101246125948 remains queued before checkout with steps=[], labels=["ubuntu-24.04"], and no assigned runner. Hosted GREEN, PostgreSQL acceptance, repository-owned 100% statement/branch coverage, current-head security completion, and a ruleset-qualifying APPROVED review are not claimed.

Keep #231 open until a successor carrying the full generic + hire repair reaches protected truth through ordinary gates. No source copy from #65, force-push, destructive rebase, self-approval, routine administrator bypass, gate weakening, 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