-
released this
2026-09-20 23:05:38 -05:00 | 56 commits to main since this releaseget_submission_feedback: the sentence half of a grade. C7, the last tool
the Canvas build plan had left, and the only phase that was ever blocked by a
calendar rather than by a decision — measured 2026-08-24, the endpoint worked and
there were ZERO graded submissions across three courses, so there was nothing to
read. Grading has started.get_gradesreturns a course total andlist_assignmentsreturns a per-assignment
score. Neither carries a word of what the grader wrote, so "why did I lose those
points" was the one coursework question this tenant could see the evidence of and
not answer — the planner has been reportinghas_feedbackon items it could not
open since C3.One request for a whole course. The bulk endpoint takes submission comments,
their HTML twins and the rubric assessment in a singleinclude[]set, so score
and commentary are two calls rather than twelve.student_ids[]is omitted
deliberately: Canvas answers the bare endpoint with the calling user's submissions
and refuses a student who asks for anyone else's, so naming the account adds a
parameter that can only make the request refusable.groupedis absent for a harder reason, and a test pins it. It silently
disablesorderandorder_direction— which would leave both accepted, ignored
and invisible from the response, with the newest feedback quietly no longer landing
on page one of a truncated read.A rubric assessment is unreadable on its own. Canvas returns it keyed by
criterion id and nothing else —{"_1234": {"points": 4.5}}— while the
descriptions live on the assignment's rubric, which is whyinclude[]=assignment
is sent and joined. An unjoinable row carriescriterion_unresolvedand a null
name rather than the id dressed up as one."blank"is a real Canvas rating id,
not a null in disguise, and is resolved like any other.posted: falsemeans WITHHELD, not empty. Canvas answers an unposted
submission under a clean 200 with the score and the comments held back, so
"nothing has been said" and "something has been said and not released" arrive in
the same shape. Those rows are returned with a note saying so instead of being
dropped for carrying no feedback — an ungraded submission, whoseposted_atis
also null, is not reported as withheld.Who wrote a comment is looked up, not inferred. A peer-reviewed assignment
puts classmates in the same array, so "not the student's own, therefore the
instructor's" is wrong rather than approximate. One roster request resolves it,
made only when a comment exists to attribute; where it fails,author_is_instructor
is ABSENT and the response says the role could not be confirmed. Same rule as
is_selfand for the same reason as 0.49.0's(unknown).Two more shapes that read as emptiness and are not. An audio or video comment
arrives with no text at all and is flaggedcomment_is_media_onlyrather than
reported as a blank remark; a quiz carriesquiz_feedback_not_included, because
per-question feedback lives in a Canvas API this server does not read — and both
quiz engines are detected, since a New Quiz carries none of the classic signals.unread_onlydeclines rather than emptying the list. Read state is reported by
the single-assignment endpoint and not by the bulk one, so the filter is real on one
path and refused on the other withunread_filter_not_appliedsaying which. It is
measured BEFORE the filter runs: taken afterwards, a course where the user has read
everything is indistinguishable from an endpoint that never reported read state, and
"you are up to date" and "this filter did not run" are opposite answers.Narrowing to one assignment changes endpoint rather than parameters.
assignment_ids[]on the bulk route has a standing report of returning no comments
for an assignment the user has not submitted to, even where staff left them — the
silent-emptiness failure this tenant keeps finding./submissions/selfis used
instead, which is also the only route that reports read state.docs/canvas-plan.mdis deleted. It was a queue that held only what was
unbuilt and said to delete it when the last item was done — that was this tool.
Its three outstanding LIVE checks moved toCLAUDE.mdrather than dying with it,
anddocs/operations.mdnow points there for recording a session's absolute cap.A defect the tests caught before it shipped: a bounded read cannot report an
absence.sinceis sent to Canvas asgraded_since, so a windowed read comes
back with a graded count of zero whether or not the course has ever been graded —
and the empty-result note reached for "nothing has been graded yet" from a window
that had excluded the evidence. Thesincecase is now tested first and says the
read was bounded. Generalised inCLAUDE.md.Canvas is at twelve tools and still has no write on its surface.
Downloads
-
Source code (ZIP)
0 downloads
-
Source code (TAR.GZ)
0 downloads
-
Source code (ZIP)