fix(remark): map indicator_ordinal → ordinal, or no feedback ever reaches a teacher - #342
Merged
Conversation
…ches a teacher loadScores selected `indicator_ordinal` and returned the rows untouched. computeS requires `ordinal` and throws on anything else, and that call sits ABOVE both of submitRemark's try/catch blocks — so the throw escaped the whole function and took the narrative, the teacher's coaching note AND the principal's confirmation with it. Scores still persisted (written before the failure) and the principal still saw the SUCCESS screen (returned before the async work), so the flow looked healthy while no teacher had ever received a note. remark-narrative-retry.worker.js has always done this mapping. The same query, mapped in one file and not the other, is the whole bug — and the worker is scheduled nowhere, so nothing drained the backlog either. Verified end to end by driving the real submitRemark: with the raw row shape it throws with teacher/principal/generated/marked all at 0; with the mapped shape both sends fire and deliveryPending is false. Tests: new remark-delivery-deps.test.js pins the boundary the two halves disagreed about — nothing exercised makeDeliveryDeps before, which is why 177 tests passed while production sent nothing. Full remark suite 182/182. Reported by Hasnat, 2026-08-17. Closes: bd-43488
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.
Reported by Hasnat, 2026-08-17:
Confirmed, and it is worse than reported — the principal's confirmation is lost too.
Root cause
remark-delivery.deps.jsselectedindicator_ordinaland returned the rows untouched:remark-rubric.js:243requiresordinaland throws on anything else. ThatcomputeScall sits atremark-delivery.service.js:100— above both try/catch blocks — so the throw escapedsubmitRemarkentirely, taking the narrative, the teacher's note andsendToPrincipalwith it.It looked healthy because scores persist before the failure point and the principal is shown
SUCCESSbefore the async delivery runs.remark-narrative-retry.worker.js:61has always done this mapping. The same query, mapped in one file and not the other, is the entire bug — and the worker is scheduled nowhere (no Procfile entry, no npm script, no cron), so nothing drained the backlog either.Verified end to end
Driving the real
submitRemark:indicator_ordinal)malformed score row (missing ordinal)—{teacher:0, principal:0, generated:0, marked:0}ordinal){teacher:1, principal:1, generated:1},deliveryPending: falseWhy the suite never caught it
remark-delivery.test.js:36hand-writes the correct shape, and nothing exercisedmakeDeliveryDeps— the code that produces the wrong one. 177 tests green while zero notes were delivered.New
remark-delivery-deps.test.jspins that boundary: whateverloadScoresreturns must be somethingcomputeSaccepts. Full remark suite 182/182.Follow-ups (deliberately not in this PR)
type: 'text'with no template fallback. A teacher who has not messaged the bot in 24h will hit Meta error131047. A teacher being evaluated is exactly the person unlikely to have messaged recently — so this may move the failure downstream rather than remove it. Worth confirming via Axiom onresponseData.error.codeafter this lands.Closes: bd-43488