feat(lab-report): note-authoritative feedback delivery (--from-note) - #19
Merged
Conversation
Each grading round is one giant vault note (recon-<lab>/REPORT.md) holding cohort facts, grades, and every student's feedback, edited in place as you grade. Add `reg-lab-report deliver --from-note <REPORT.md>` (mutually exclusive with --cohort): parse the per-student blocks and render each repo's FEEDBACK.md straight from the note, so hand-authored feedback is delivered verbatim and is never re-derived from a digest cohort and clobbered. - lectern/feedback_note.py: parse the note's per-student blocks into rows (self-describing N components, +EC, __/— = ungraded -> skipped). The block grammar is a contract (docs/design/feedback-from-note.md). - feedback_deliver: render_feedback_md_from_note (generic N-component table); deliver() takes an injectable render= and reads total/grand/components from the row; main() adds --from-note xor --cohort. - feedback_log: tolerant of note-path entries (component breakdown, per-row grand); digest Auto/Writeup path unchanged. The signed feedback-branch -> PR-close -> signed merge-to-main flow, dry-run default, and idempotency are untouched; both paths share deliver(). Full suite green (387 passed). Fits lectern doctrine: the vault is the proprietary record, the tool a deterministic renderer over a parseable contract. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015cY2osrcunEXb5a8xtTy2V
CHANGELOG, SKILL.md, README.md deliver entries + a design doc (docs/design/feedback-from-note.md) for the note-authoritative feedback path. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_015cY2osrcunEXb5a8xtTy2V
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.
What
Adds
reg-lab-report deliver --from-note <REPORT.md>— the grading-round vault note is now the authoritative source of student feedback. Each round is one note (recon-<lab>/REPORT.md) holding cohort facts, grades, and every student's feedback edited in place;deliverparses the per-student blocks and renders each repo'sFEEDBACK.mdverbatim, so hand-authored feedback is never re-derived from a digest cohort and clobbered.Why
Doctrine (2026-06-28): one giant note per grading round. The existing
deliver --cohortre-rendersFEEDBACK.mdfrom a template + digest cohort, which would overwrite feedback authored in the note. Inverting the source of truth fits lectern doctrine: the vault is the proprietary record; the tool is a deterministic renderer over a parseable contract (same principle as theresult.json/ deliverable-naming contracts).How
lectern/feedback_note.py(new) — parse the note's per-student blocks into rows; self-describing N components (+extra credit),__/—= ungraded → skipped.feedback_deliver—render_feedback_md_from_note(generic N-component table);deliver(..., render=)injectable + readstotal/grand/componentsfrom the row;main()adds--from-note(xor--cohort).feedback_log— tolerant of note-path entries (component breakdown, per-row grand); the digest Auto/Writeup path is unchanged.The signed feedback-branch → PR-close → signed merge-to-main flow, dry-run default, and idempotency are untouched; both paths share
deliver().Tests / docs
tests/test_feedback_note.py+ extended deliver tests (synthetic Batman cohort). 387 passed, 0 regressions.docs/design/feedback-from-note.md.🤖 Generated with Claude Code