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.
Finding
Canonical owner is #64. At predecessor
62a6b7ac2908dce2ea760c13123f8685a6f0eb5c, generic People application entry points andaccept_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_kindmay be a runtimestrsubtype, and policy comparison can execute subclass equality/inequality behavior. A retained command can therefore be rewritten withobject.__setattr__during authorization. Changing Employmentperson_record_id, Positionjob_profile_id, Assignmentposition_record_id, or hire PII such asdisplay_nameleaves 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
f7415084d801bc06be316b022f41f53763197882adds 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
5a6354a94a4098509d68a6d413c0dbe8b236f94fadds the symmetric confirmed-hire regression: authorization comparison rewrites retaineddisplay_name, butHireAcceptancePortmust 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
e4d538c3e5c0707b650e4eeefb7d91dc4611fe9eimportsdataclasses.replaceinmutations.pyand creates a fresh exact command immediately after each exact outer-type gate. Current9771be6d65bef77408cd5ad1ae316f0a8d8fb5e3applies the same rule inhire.py. Expected-result snapshots, purpose-bound authorization, and mutation-port calls use only the detached command.From #229 head
62a6b7ac…to current9771be6…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
9771be6d65bef77408cd5ad1ae316f0a8d8fb5e3against protecteddevelop@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 reportedgit diff --checkclean. 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, Security33943808260, SAST33943808200, and CodeQL PR33943808117. Foundation job101246125948remains queued before checkout withsteps=[],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-qualifyingAPPROVEDreview 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.