Follow-up to #264 (CR dynamic-approval field routing). #264 froze the routed/approved field and its mapped values post-submit. Two identity fields on the change request remain writable post-submit and should be frozen in the same "frozen once approved" class.
Problem
registrant_id — if swapped after approval, the approved change is applied to a different person than the one reviewed. This is the more serious of the two.
request_type_id — a nit from review; a swap could recompute detail_res_model and change what the CR means.
Why it needs its own PR
The freeze must use the env.su discriminator, NOT a context flag (a context flag is client-forgeable). The create_group apply strategy legitimately writes registrant_id post-approval under sudo, so the guard must allow the sudo write path while blocking a non-superuser (owning cr_user) write. Doing this correctly requires non-superuser tests — the current test env runs as superuser, so a naive test would pass vacuously.
Proposed work
- Freeze
registrant_id (and request_type_id) once the CR is submitted/approved, keyed on env.su so the sudo apply path is unaffected.
- Add non-superuser (owning
cr_user) tests that attempt the post-submit swap and assert it is rejected, while the sudo apply path still succeeds.
The reviewer deemed request_type_id out-of-scope/non-blocking for #264 and did not flag registrant_id; both are captured here for a deliberate follow-up.
Source: internal/plans/sec-cr-dynamic-approval-field.md ("Deferred follow-up").
Follow-up to #264 (CR dynamic-approval field routing). #264 froze the routed/approved field and its mapped values post-submit. Two identity fields on the change request remain writable post-submit and should be frozen in the same "frozen once approved" class.
Problem
registrant_id— if swapped after approval, the approved change is applied to a different person than the one reviewed. This is the more serious of the two.request_type_id— a nit from review; a swap could recomputedetail_res_modeland change what the CR means.Why it needs its own PR
The freeze must use the
env.sudiscriminator, NOT a context flag (a context flag is client-forgeable). Thecreate_groupapply strategy legitimately writesregistrant_idpost-approval under sudo, so the guard must allow the sudo write path while blocking a non-superuser (owningcr_user) write. Doing this correctly requires non-superuser tests — the current test env runs as superuser, so a naive test would pass vacuously.Proposed work
registrant_id(andrequest_type_id) once the CR is submitted/approved, keyed onenv.suso the sudo apply path is unaffected.cr_user) tests that attempt the post-submit swap and assert it is rejected, while the sudo apply path still succeeds.The reviewer deemed
request_type_idout-of-scope/non-blocking for #264 and did not flagregistrant_id; both are captured here for a deliberate follow-up.Source:
internal/plans/sec-cr-dynamic-approval-field.md("Deferred follow-up").