1
0

Update README and saltire docs to current behavior

The README now documents the daily workflow (working date, live mode
vs printed lists, regenerate semantics, full day-editor editability),
describes cycle mode's rolling rotation accurately, repairs the
custom-parameters section, and points to the saltire testing guide,
which gains resume-after-a-break instructions.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
This commit is contained in:
2026-07-31 19:16:54 -07:00
parent 1a4e33a26e
commit c4cb3307fa
2 changed files with 72 additions and 14 deletions

View File

@@ -21,9 +21,34 @@ Selection uses the same weighting as the manual system it replaces: each
answered call divides a student's weight by the course's weight factor
(default 2), so students who have answered more questions become
progressively less likely to be called. Each course can instead use
"cycle" mode, which shuffles the roster and calls everyone exactly once.
These, along with whether students can see their own assessments, are
per-course settings.
"cycle" mode, a rolling rotation through the roster in random order:
everyone is called once before anyone repeats, batches take the next
students in the current pass (continuing across lists and class days),
and skipped calls don't count as a turn. These, along with whether
students can see their own assessments, are per-course settings.
## Daily use
The instructor page works against a selectable date (defaulting to
today), so printing tomorrow's list a day in advance just means
switching the working date. There are two ways to run a class, per
day and freely mixed:
- **Live mode**: a "call next student" button shows who's up (photo,
name, pronouns) with one-tap outcomes — the assessment levels,
missing (absent without an opt-out), or skip (as if the call never
happened).
- **Printed list**: generate a numbered list of any length, print it,
and mark it up on paper; after class, enter the outcomes in the day
editor. Generating is safe by design: when an unused list already
exists the button becomes an explicit "regenerate", and a warning
appears only if the day already has recorded outcomes (which are
always preserved).
The day editor allows full correction of the record: change any call's
status, assessment, or note; delete lines entirely (effectively
excusing the student); and add calls after the fact for anyone on the
roster.
## Layout
@@ -96,8 +121,8 @@ churn at the start of a term):
Courses whose Canvas end date has passed are skipped automatically.
Student names come from Canvas display names, which already reflect
preferred names. Pronouns require one extra piece of Developer Key
configuration: add a custom parameter
preferred names. Four custom parameters on the Developer Key give the
tool everything else it can use from Canvas:
```
pronouns=$com.instructure.Person.pronouns
@@ -106,15 +131,14 @@ course_end=$Canvas.course.endAt
grading_scheme=$com.instructure.Course.gradingScheme
```
The course dates bound the schedule and date pickers; the tool works
fine without them when a course has no dates set in Canvas.
to the key. Canvas then includes each person's pronouns in launches
and in the roster data (the tool requests memberships scoped to the
resource link, which is what makes Canvas attach per-member custom
fields). Pronouns appear on the live call card, printed call lists,
and each student's own page. If the account has pronouns disabled,
everything simply shows without them.
Pronouns then arrive in launches and in the roster data (the tool
requests memberships scoped to the resource link, which is what makes
Canvas attach per-member custom fields) and appear on the live call
card, printed lists, and each student's own page. The course dates
bound the schedule and date pickers, and the grading scheme becomes
importable into the grade display scale with one click in settings.
All four degrade gracefully: a course or account without them simply
does without.
## Opt-outs
@@ -178,3 +202,9 @@ as real NRPS data, so everything past the launch behaves identically.
Dev mode also relaxes the cookie settings that Canvas's iframe
embedding requires in production (SameSite=None; Secure), which would
otherwise break plain-http localhost use.
The one thing dev mode cannot exercise is the real OIDC/JWT handshake
itself. For that, the app is tested against the saltire LTI platform
emulator — a hosted fake LMS that performs genuine LTI 1.3 launches
and answers NRPS requests. The full setup and re-run instructions are
in `docs/SALTIRE.md`.

View File

@@ -69,6 +69,34 @@ On https://saltire.lti.app → Test Platform → **Security Model**:
`http://purl.imsglobal.org/vocab/lis/v2/membership#Learner`, save,
and Connect again — you land on /me.
## Picking the test setup back up
With the configuration saved under a saltire account (sign in, then
Save), resuming a test session is short:
1. Start the local server (the keys and TLS cert in `instance/` are
already there):
```
COLDCALL_SECRET_KEY=saltire-test .venv/bin/python -m flask \
--app coldcall_lti run --port 5443 \
--cert instance/tls-cert.pem --key instance/tls-key.pem
```
2. If the browser has forgotten the self-signed certificate, open
https://localhost:5443/healthz and click through the warning again.
3. Sign in at https://saltire.lti.app → Test Platform, confirm the
saved configuration loaded (Security Model should show LTI 1.3 and
the localhost URLs), and press **Connect**.
4. If the launch fails at JWT validation or roster sync, compare the
token/jwks URLs shown in Platform Details against
`instance/lti_config.json` — the session id may have changed; copy
the new values in. Everything else should be stable.
To test as a student instead of the instructor, change the role under
**User** to `.../membership#Learner`, Save, and Connect; switch back
to `#Instructor` the same way.
## Caveats
- **The token and jwks URLs embed a saltire session id** (the