feat(marking): tie grid rows to components; per-component % in prose#54
Open
hyperpolymath wants to merge 1 commit into
Open
Conversation
Each per-question grid row gains an optional component_id linking it
back to a rubric component. The composer aggregates marks per component
and surfaces the numeric performance inline in the did_well prose.
Rubric pack changes
- default_questions rows now carry "component_id":
* ou_3_part: Q1 -> reflective, Q2 -> planning, Q3 -> essay
* single_essay: q1 -> essay
- Question labels for ou_3_part updated to show the mapping
("Question 1 (A reflective)", etc.) so the linkage is visible
without inspecting source
Composer module
- aggregate_by_component/1 public API: %{component_id => %{total, max, percentage}}
* Groups rows by component_id; ignores rows with no/blank component_id
* Components with no parseable rows are absent from the result map
* Returns %{} for nil or non-list input
- compose/1 result map gains :per_component (the aggregate map)
- component_good_sentence appends " (scoring X / Y =~ Z%)" when the
per-component aggregate is available, so the did_well prose surfaces
the numeric performance without losing the existing rating language
- Components without numeric data simply omit the suffix; no regression
for the override-only path
LiveView
- Hidden component_id input per row so the link survives form submit
- When the live grid total is shown, also render a per-component
breakdown card grid below it, one card per rubric component with
parseable marks
Tests (34 total, all passing — 26 prior + 8 new)
- aggregate_by_component: per-component groupings, multi-row merge,
drop-untagged-rows, drop-empty-components, nil/non-list input
- compose/1 with per-component questions: did_well embeds the
percentages, components without numeric data omit suffix gracefully,
single_essay rubric: per-component matches overall
Verified locally via standalone elixirc + ExUnit (34/0).
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This was referenced Jun 10, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Summary
The per-question grid and the per-component ratings are no longer parallel tracks. Each grid row carries an optional `component_id` linking it back to a rubric component; the composer aggregates marks per component and surfaces the numeric performance inline in the `did_well` prose.
What ships in this PR
Sample output
Inputs: ou_3_part rubric, Q1=22/25 reflective+strong, Q2=18/25 planning+sound, Q3=40/50 essay+sound.
Out of scope (follow-ups)
Tests
Test plan
Generated with Claude Code.