Accept readinessScoreFeedback in workItemUpdate mutation (stacked on !252884)
What does this MR do and why?
Adds readinessScoreFeedback as a writable argument on WorkItemWidgetAgentPlanInput, accepted by the workItemUpdate mutation and gated on the existing workplan_score feature flag.
This is a restacked version of !252885 (closed). The content is the same, but the branch is stacked on the GraphQL read branch instead of the model branch.
This MR also mirrors the flag-off error behaviour introduced for readiness_score in !253065 (merged): passing readinessScoreFeedback while workplan_score is disabled now raises an explicit callback error instead of silently dropping the param.
Why restack
The argument copies its description from the read-path field:
description: copy_field_description(::Types::WorkItems::Widgets::AgentPlanType, :readiness_score_feedback)That field is defined in !252884 (merged). On the original !252885 (closed) branch, which targets the model branch, AgentPlanType has no readiness_score_feedback field, so copy_field_description has nothing to copy from. Stacking on !252884 (merged) gives the argument a real field to reference.
Merge order is therefore !252883 (merged), then !252884 (merged), then this MR. Retarget to master once the parents merge.
What changes
ee/app/graphql/types/work_items/widgets/agent_plan_input_type.rb: adds thereadiness_score_feedbackargument (String,required: false,experiment: { milestone: '19.4' }).ee/app/services/work_items/callbacks/agent_plan.rb: adds:readiness_score_feedbacktoALLOWED_PARAMS, adds areadiness_score_feedback_param?predicate gated onworkplan_score, includes it in thehandle_agent_plan_changeguard, and assigns the attribute. Whenreadiness_score_feedbackis supplied but the flag is off,raise_erroris called with a clear message (mirroring thereadiness_scorebehaviour). A feedback-only change does not fireAGENT_PLAN_CREATEorAGENT_PLAN_UPDATE.doc/api/graphql/reference/_index.md: updated GraphQL reference docs.locale/gitlab.pot: adds the i18n entry for the new flag-off error message.- Specs: input type argument list, plus callback coverage for feedback-only params, feedback with the flag off (now expects an error), feedback alongside content, score and feedback staged for a single save, and the absence of agent-plan events for feedback-only changes.
How to set up and validate locally
The source branch is stacked on !252884 (merged), which in turn includes !252883 (merged), so checking it out gives you the model column, the read field, and the write argument together.
-
Check out the branch and make sure migrations are up to date:
git checkout duo/feature/617982-readiness-score-feedback-graphql-write-stacked bin/rails db:migrate -
In
rails console, enable the flag for a group and get a work item global ID (the namespace is derived from the work item, so the flag is checked against its root ancestor):group = Group.find_by_full_path('flightjs') Feature.enable(:workplan_score, group) work_item = group.work_items.first # or any work item under that group work_item.to_global_id.to_s -
Open the GraphiQL explorer at
/-/graphql-explorerand run the mutation with the global ID from the previous step:mutation { workItemUpdate(input: { id: "gid://gitlab/WorkItem/1" agentPlanWidget: { readinessScoreFeedback: "Add **acceptance criteria**." } }) { errors workItem { widgets { ... on WorkItemWidgetAgentPlan { content readinessScore readinessScoreFeedback readinessScoreFeedbackHtml } } } } }Expected:
errorsis empty,readinessScoreFeedbackreturns"Add **acceptance criteria**.",readinessScoreFeedbackHtmlrendersacceptance criteriainside a<strong>tag, andcontentis unchanged. -
Verify that a score and its feedback land on one record. Re-run the mutation with
agentPlanWidget: { readinessScore: 80, readinessScoreFeedback: "Add acceptance criteria." }and check the record count in the console:WorkItems::AgentPlan.countExpected: both fields resolve to the new values and the count is unchanged, confirming a single save rather than a second plan row.
-
Verify the flag gate. Run
Feature.disable(:workplan_score, group)in the console and re-run the mutation with different feedback. Expected:errorscontains a message mentioningworkplan_score, andreadinessScoreFeedbackretains its previous value — the param is rejected rather than silently dropped. -
Verify that a feedback-only change fires no agent plan event. Tail the log while running a feedback-only mutation:
tail -f log/development.log | grep -i agent_planExpected: no
work_item_agent_plan_createorwork_item_agent_plan_updateevent. -
Verify the length validation by sending feedback longer than
WorkItems::AgentPlan::CONTENT_LENGTH_MAX. Expected: the mutation returns a validation message inerrorsinstead of succeeding. -
Run the specs and the GraphQL docs check:
bin/rspec ee/spec/graphql/types/work_items/widgets/agent_plan_input_type_spec.rb \ ee/spec/services/work_items/callbacks/agent_plan_spec.rb bundle exec rake gitlab:graphql:check_docs
One gotcha when poking at this by hand: readiness_score_feedback is externally stored, so it does not roll back with a transaction and a stale in-memory record can mislead you. Call reload on the plan before asserting anything. This is also why the spec switched its agent_plan from let_it_be to let!.
References
- Issue: #617982 (closed)
- MR 1 (model): !252883 (merged)
- MR 2 (read, target of this MR): !252884 (merged)
- Original unstacked version: !252885 (closed)
- Reference fix (readiness_score flag-off error): !253065 (merged)
MR acceptance checklist
Evaluate this MR against the MR acceptance checklist. It helps you analyze changes to reduce risks in quality, performance, reliability, security, and maintainability.