Releases: Ryfter/canvas-toolchain
Release list
v2.1.0
Canvas Toolchain Installer
What's new in v2.1.0
One product, one Releases page — and the update notice works again.
- Your toolchain will tell you about updates again. In 2.0, publishing a module accidentally took over the "latest release" spot, and a side effect was that the toolchain quietly stopped noticing when a new toolchain version was available. That's fixed: the update check now looks only at real toolchain releases, so the one-line "update available" nudge is reliable again. If you're on an older version and haven't been prompted in a while, this is why — update to 2.1.0 and it starts working.
- Modules are a directory, not a pile of releases. Add-on modules (like the Announcements Auditor) and companion programs (like Canvas Backup) are now listed in one place — see the module directory. The Releases page shows only Canvas Toolchain itself, the way it should.
- You still install modules the same way — just ask Claude, e.g. "install the announcements module," and confirm when it shows you what it will do. Nothing about the install experience changed.
- Companion programs are listed and explained, never auto-installed. Things like Canvas Backup that run alongside the toolchain now appear in the directory with a description and a link, so you can decide for yourself. The toolchain will never download or run them on its own.
- Security hardening under the hood. This release closes several ways a tampered module catalog could have pointed the toolchain at the wrong download, and tightens how module files are validated before they ever run. Nothing you do differently — it's all in the plumbing that decides whether a module is safe to load.
Nothing changes if you ignore all of this: every existing tool and workflow behaves exactly as it did in 2.0, and your installed modules keep working.
Full diff: v2.0.0...v2.1.0
What's new in v2.0.0
The 2.0 headline: modules are now drop-in. New capabilities can be published and installed without waiting for an installer release — and the first one ships today.
The module channel
- Browse and install modules by asking. Two new tools do the work:
browse_module_catalogshows what's available, installed, or updatable;install_moduleinstalls one. Installing is always deliberate — the first call only previews what would be downloaded (name, version, size, source, checksum); call again withconfirm: trueto proceed. Modules take effect on your next Claude reconnect, anduninstall_moduleremoves them cleanly. - Security is the centerpiece. Every module is a single self-contained file whose checksum is pinned in a catalog only this repository can publish. The checksum is verified when you install and re-verified every time the toolchain starts — a tampered download, a corrupted file, or a hand-edited artifact simply never runs. And nothing a module does can crash the toolchain: a broken module is skipped with a clear warning, never loaded.
- The installer shows what's out there. A new "Additional modules" section lists catalog modules with checkboxes — but checking one only queues a request. Next time you open Claude it offers to install them, and your chat confirmation remains the only thing that authorizes code. The installer itself never downloads modules.
- Updates announce themselves. When an installed module has a newer version, the same gentle one-line notice that announces toolchain updates tells you — upgrading is one confirmed
install_modulecall, and the previous version is kept until the new one proves it loads, so a bad update can be rolled back.
First channel module: Announcements Auditor
audit_announcementsfinds the classic course-copy gotcha: scheduled announcements that silently kept last term's fire dates. It lists a course's announcements and flags stale ones (dates already passed, or outside your term window if you give one).recreate_announcementmakes a corrected copy with the right fire date — preview first, create onconfirm: true, and it never deletes anything (you remove the stale original in Canvas yourself).- Uses your existing Canvas token; nothing new to set up. Install it by asking: "install the announcements module."
Nothing changes if you ignore all of this: every existing tool and workflow behaves exactly as it did in v1.11.x, and the five bundled modules still ship in the installer.
Full diff: v1.11.1...v2.0.0
What's new in v1.11.1
A small hardening release — no new tools, no setup changes, nothing to migrate.
Safer storage for your Canvas credentials
- The institution config is now written atomically with owner-only permissions.
~/.canvas-design-mcp/institution.jsonholds your Canvas API token (and WAVE key, if you set one). It is now saved via a temp-file-plus-rename write with0o600permissions on Mac/Linux, so a crash mid-save can never leave a partial or world-readable config. Existing configs keep working unchanged. (#119) CANVAS_DESIGN_HOME— the environment variable the coordinator server already honored for this directory now works everywhere, letting tests and multi-profile setups point the toolchain at an alternate home.
Generic examples throughout
- Documentation, sample configs, and test fixtures now use neutral placeholders (
example.edu-style hostnames and placeholder course IDs) instead of one university's real values. Purely cosmetic for users — nothing behavioral. (#118)
Full diff: v1.11.0...v1.11.1
What's new in v1.11.0
Accessibility Phase 3: your institution's policy becomes the anchor for every check, and two new tools join the kit — one to keep the policy current, one for optional deep checks via WAVE. Nothing changes until you opt in: with no policy configured, every check behaves exactly as it did in v1.10.x.
Your institution's accessibility policy, on file
- New tool
review_accessibility_policy— records your institution's accessibility policy links, the WCAG conformance level your courses must meet (default stays WCAG 2.1 AA, the ADA Title II baseline), and how often you want to be reminded to re-read the policy (default every 4 weeks). Call it withconfirm: trueafter re-reading the policy and it stamps the date; when the reminder comes due, a gentle nudge appears at the end of accessibility reports — it never blocks anything. - The required level moves the gate line, not the checks. Every page is still checked against the full WCAG 2.2 catalog; the policy level only decides which findings can hold a publish back. Set it to 2.2 AA when your institution adopts it and the gate follows — no other changes needed.
A preview of WCAG 3 (optional, informational only)
- Turn on
wcag3Advisoryin the policy and accessibility reports gain a short section mapping your findings to the corresponding WCAG 3 draft outcomes — a low-effort way to watch where the standard is heading. It is clearly labeled as draft material and can never block a publish.
Deep checks with WAVE (WebAIM)
- New tool
wave_deep_check— runs a publicly visible page through the paid WAVE API for a second opinion beyond the built-in engines. Spending is always deliberate: the first call only previews the cost (~2 credits) and runs nothing; call again withconfirm: trueto spend. Login-gated Canvas pages are refused before any credits are spent — for those, the report points you at the free WAVE browser extension instead.
Sturdier record-keeping at publish time
- The per-page
approvalsanda11yAcknowledgmentsmaps inpublish_courseare now keyed by each page's output file path. A bare filename still works as a convenience — but only when it matches exactly one page, so an acknowledgment can never silently apply to a page you didn't review. (#108)
Full diff: v1.10.1...v1.11.0
What's new in v1.10.1
A small polish release for the v1.10.0 accessibility publishing gate — clearer guidance when a publish is held back, and tidier record-keeping. No new tools, no setup changes.
Clearer instructions when a course publish is held back
- The block message now tells you exactly what to do. During a whole-course publish, a page can pass the up-front accessibility check but still get held at the final step — the page's HTML is re-checked after widget links are swapped for their Canvas URLs, and that final version is what students actually get. Previously the hold message pointed at an option that
publish_coursedoesn't accept. Now it spells out the exacta11yAcknowledgmentsentry to pass for that file — naming each failing criterion when the failures are clear-cut, or a simpletruefor near-misses — plusresume:trueso the publish continues right where it stopped. (#112)
Consistent record-keeping in the acknowledgment trail
- Every entry in
.a11y/acknowledgments.jsonnow identifies its page the same way — by the page's output file path. Previously, acknowledgments recorded for pages used the Canvas page title while those for assignments used the file path, so one course's audit trail mixed two labeling styles. Existing entries stay exactly as they are and remain valid; nothing to migrate. (#113)
Full diff: [v1.10.0...v1.10.1](https://github.com/Ryfter/canvas-toolchain/compare/v1.10...
v2.0.0
Canvas Toolchain Installer
What's new in v2.0.0
The 2.0 headline: modules are now drop-in. New capabilities can be published and installed without waiting for an installer release — and the first one ships today.
The module channel
- Browse and install modules by asking. Two new tools do the work:
browse_module_catalogshows what's available, installed, or updatable;install_moduleinstalls one. Installing is always deliberate — the first call only previews what would be downloaded (name, version, size, source, checksum); call again withconfirm: trueto proceed. Modules take effect on your next Claude reconnect, anduninstall_moduleremoves them cleanly. - Security is the centerpiece. Every module is a single self-contained file whose checksum is pinned in a catalog only this repository can publish. The checksum is verified when you install and re-verified every time the toolchain starts — a tampered download, a corrupted file, or a hand-edited artifact simply never runs. And nothing a module does can crash the toolchain: a broken module is skipped with a clear warning, never loaded.
- The installer shows what's out there. A new "Additional modules" section lists catalog modules with checkboxes — but checking one only queues a request. Next time you open Claude it offers to install them, and your chat confirmation remains the only thing that authorizes code. The installer itself never downloads modules.
- Updates announce themselves. When an installed module has a newer version, the same gentle one-line notice that announces toolchain updates tells you — upgrading is one confirmed
install_modulecall, and the previous version is kept until the new one proves it loads, so a bad update can be rolled back.
First channel module: Announcements Auditor
audit_announcementsfinds the classic course-copy gotcha: scheduled announcements that silently kept last term's fire dates. It lists a course's announcements and flags stale ones (dates already passed, or outside your term window if you give one).recreate_announcementmakes a corrected copy with the right fire date — preview first, create onconfirm: true, and it never deletes anything (you remove the stale original in Canvas yourself).- Uses your existing Canvas token; nothing new to set up. Install it by asking: "install the announcements module."
Nothing changes if you ignore all of this: every existing tool and workflow behaves exactly as it did in v1.11.x, and the five bundled modules still ship in the installer.
Full diff: v1.11.1...v2.0.0
What's new in v1.11.1
A small hardening release — no new tools, no setup changes, nothing to migrate.
Safer storage for your Canvas credentials
- The institution config is now written atomically with owner-only permissions.
~/.canvas-design-mcp/institution.jsonholds your Canvas API token (and WAVE key, if you set one). It is now saved via a temp-file-plus-rename write with0o600permissions on Mac/Linux, so a crash mid-save can never leave a partial or world-readable config. Existing configs keep working unchanged. (#119) CANVAS_DESIGN_HOME— the environment variable the coordinator server already honored for this directory now works everywhere, letting tests and multi-profile setups point the toolchain at an alternate home.
Generic examples throughout
- Documentation, sample configs, and test fixtures now use neutral placeholders (
example.edu-style hostnames and placeholder course IDs) instead of one university's real values. Purely cosmetic for users — nothing behavioral. (#118)
Full diff: v1.11.0...v1.11.1
What's new in v1.11.0
Accessibility Phase 3: your institution's policy becomes the anchor for every check, and two new tools join the kit — one to keep the policy current, one for optional deep checks via WAVE. Nothing changes until you opt in: with no policy configured, every check behaves exactly as it did in v1.10.x.
Your institution's accessibility policy, on file
- New tool
review_accessibility_policy— records your institution's accessibility policy links, the WCAG conformance level your courses must meet (default stays WCAG 2.1 AA, the ADA Title II baseline), and how often you want to be reminded to re-read the policy (default every 4 weeks). Call it withconfirm: trueafter re-reading the policy and it stamps the date; when the reminder comes due, a gentle nudge appears at the end of accessibility reports — it never blocks anything. - The required level moves the gate line, not the checks. Every page is still checked against the full WCAG 2.2 catalog; the policy level only decides which findings can hold a publish back. Set it to 2.2 AA when your institution adopts it and the gate follows — no other changes needed.
A preview of WCAG 3 (optional, informational only)
- Turn on
wcag3Advisoryin the policy and accessibility reports gain a short section mapping your findings to the corresponding WCAG 3 draft outcomes — a low-effort way to watch where the standard is heading. It is clearly labeled as draft material and can never block a publish.
Deep checks with WAVE (WebAIM)
- New tool
wave_deep_check— runs a publicly visible page through the paid WAVE API for a second opinion beyond the built-in engines. Spending is always deliberate: the first call only previews the cost (~2 credits) and runs nothing; call again withconfirm: trueto spend. Login-gated Canvas pages are refused before any credits are spent — for those, the report points you at the free WAVE browser extension instead.
Sturdier record-keeping at publish time
- The per-page
approvalsanda11yAcknowledgmentsmaps inpublish_courseare now keyed by each page's output file path. A bare filename still works as a convenience — but only when it matches exactly one page, so an acknowledgment can never silently apply to a page you didn't review. (#108)
Full diff: v1.10.1...v1.11.0
What's new in v1.10.1
A small polish release for the v1.10.0 accessibility publishing gate — clearer guidance when a publish is held back, and tidier record-keeping. No new tools, no setup changes.
Clearer instructions when a course publish is held back
- The block message now tells you exactly what to do. During a whole-course publish, a page can pass the up-front accessibility check but still get held at the final step — the page's HTML is re-checked after widget links are swapped for their Canvas URLs, and that final version is what students actually get. Previously the hold message pointed at an option that
publish_coursedoesn't accept. Now it spells out the exacta11yAcknowledgmentsentry to pass for that file — naming each failing criterion when the failures are clear-cut, or a simpletruefor near-misses — plusresume:trueso the publish continues right where it stopped. (#112)
Consistent record-keeping in the acknowledgment trail
- Every entry in
.a11y/acknowledgments.jsonnow identifies its page the same way — by the page's output file path. Previously, acknowledgments recorded for pages used the Canvas page title while those for assignments used the file path, so one course's audit trail mixed two labeling styles. Existing entries stay exactly as they are and remain valid; nothing to migrate. (#113)
Full diff: v1.10.0...v1.10.1
What's new in v1.10.0
Accessibility moves from advice to a gate — with you as the final decision-maker. Since v1.9.0 the toolchain has run a full WCAG 2.2 conformance check on every page and reported the results. This release makes that check matter at publish time: it can now hold a page back until you've seen the problems and decided to proceed anyway.
The two-tier publishing gate
When you publish to Canvas (publish_to_canvas, or a whole course with publish_course), each page's accessibility result decides what's required:
- Clean page — publishes exactly as before.
- Near-miss (borderline) — publishes once you acknowledge it, by passing
acknowledgeAccessibility: true. A quick "yes, I've seen it." - Clear failure — publishes once you acknowledge each failing criterion by name (e.g.
["1.4.3", "1.3.1"]). If the block message lists three failures, your acknowledgment has to name all three — so you can't wave past problems you haven't actually looked at.
You are always the final arbiter. Nothing is ever permanently blocked: the gate exists to make sure a failure is a decision, not an accident. The blocked message spells out exactly what to acknowledge and how. The FERPA scan and the Canvas-HTML validation checks are unchanged and still absolute — those are not accessibility findings and cannot be acknowledged away. The manual generate-and-paste workflow is not gated at all.
A record of what you approved, and a worklist of what to revisit
- Acknowledgment trail. Every acknowledgment is recorded in a per-course
.a11y/acknowledgments.json— what page, which criteria, when, against which conformance level. An append-only log you can point to later. - Review queue. Pages that were borderline (or that a course audit flagged) land on a
.a11y/review-queue.jsonworklist, sorted worst-first so the closest calls are at the top. Two new tools work it:accessibility_review_queue— list the pages...
v1.11.1
Canvas Toolchain Installer
What's new in v1.11.1
A small hardening release — no new tools, no setup changes, nothing to migrate.
Safer storage for your Canvas credentials
- The institution config is now written atomically with owner-only permissions.
~/.canvas-design-mcp/institution.jsonholds your Canvas API token (and WAVE key, if you set one). It is now saved via a temp-file-plus-rename write with0o600permissions on Mac/Linux, so a crash mid-save can never leave a partial or world-readable config. Existing configs keep working unchanged. (#119) CANVAS_DESIGN_HOME— the environment variable the coordinator server already honored for this directory now works everywhere, letting tests and multi-profile setups point the toolchain at an alternate home.
Generic examples throughout
- Documentation, sample configs, and test fixtures now use neutral placeholders (
example.edu-style hostnames and placeholder course IDs) instead of one university's real values. Purely cosmetic for users — nothing behavioral. (#118)
Full diff: v1.11.0...v1.11.1
What's new in v1.11.0
Accessibility Phase 3: your institution's policy becomes the anchor for every check, and two new tools join the kit — one to keep the policy current, one for optional deep checks via WAVE. Nothing changes until you opt in: with no policy configured, every check behaves exactly as it did in v1.10.x.
Your institution's accessibility policy, on file
- New tool
review_accessibility_policy— records your institution's accessibility policy links, the WCAG conformance level your courses must meet (default stays WCAG 2.1 AA, the ADA Title II baseline), and how often you want to be reminded to re-read the policy (default every 4 weeks). Call it withconfirm: trueafter re-reading the policy and it stamps the date; when the reminder comes due, a gentle nudge appears at the end of accessibility reports — it never blocks anything. - The required level moves the gate line, not the checks. Every page is still checked against the full WCAG 2.2 catalog; the policy level only decides which findings can hold a publish back. Set it to 2.2 AA when your institution adopts it and the gate follows — no other changes needed.
A preview of WCAG 3 (optional, informational only)
- Turn on
wcag3Advisoryin the policy and accessibility reports gain a short section mapping your findings to the corresponding WCAG 3 draft outcomes — a low-effort way to watch where the standard is heading. It is clearly labeled as draft material and can never block a publish.
Deep checks with WAVE (WebAIM)
- New tool
wave_deep_check— runs a publicly visible page through the paid WAVE API for a second opinion beyond the built-in engines. Spending is always deliberate: the first call only previews the cost (~2 credits) and runs nothing; call again withconfirm: trueto spend. Login-gated Canvas pages are refused before any credits are spent — for those, the report points you at the free WAVE browser extension instead.
Sturdier record-keeping at publish time
- The per-page
approvalsanda11yAcknowledgmentsmaps inpublish_courseare now keyed by each page's output file path. A bare filename still works as a convenience — but only when it matches exactly one page, so an acknowledgment can never silently apply to a page you didn't review. (#108)
Full diff: v1.10.1...v1.11.0
What's new in v1.10.1
A small polish release for the v1.10.0 accessibility publishing gate — clearer guidance when a publish is held back, and tidier record-keeping. No new tools, no setup changes.
Clearer instructions when a course publish is held back
- The block message now tells you exactly what to do. During a whole-course publish, a page can pass the up-front accessibility check but still get held at the final step — the page's HTML is re-checked after widget links are swapped for their Canvas URLs, and that final version is what students actually get. Previously the hold message pointed at an option that
publish_coursedoesn't accept. Now it spells out the exacta11yAcknowledgmentsentry to pass for that file — naming each failing criterion when the failures are clear-cut, or a simpletruefor near-misses — plusresume:trueso the publish continues right where it stopped. (#112)
Consistent record-keeping in the acknowledgment trail
- Every entry in
.a11y/acknowledgments.jsonnow identifies its page the same way — by the page's output file path. Previously, acknowledgments recorded for pages used the Canvas page title while those for assignments used the file path, so one course's audit trail mixed two labeling styles. Existing entries stay exactly as they are and remain valid; nothing to migrate. (#113)
Full diff: v1.10.0...v1.10.1
What's new in v1.10.0
Accessibility moves from advice to a gate — with you as the final decision-maker. Since v1.9.0 the toolchain has run a full WCAG 2.2 conformance check on every page and reported the results. This release makes that check matter at publish time: it can now hold a page back until you've seen the problems and decided to proceed anyway.
The two-tier publishing gate
When you publish to Canvas (publish_to_canvas, or a whole course with publish_course), each page's accessibility result decides what's required:
- Clean page — publishes exactly as before.
- Near-miss (borderline) — publishes once you acknowledge it, by passing
acknowledgeAccessibility: true. A quick "yes, I've seen it." - Clear failure — publishes once you acknowledge each failing criterion by name (e.g.
["1.4.3", "1.3.1"]). If the block message lists three failures, your acknowledgment has to name all three — so you can't wave past problems you haven't actually looked at.
You are always the final arbiter. Nothing is ever permanently blocked: the gate exists to make sure a failure is a decision, not an accident. The blocked message spells out exactly what to acknowledge and how. The FERPA scan and the Canvas-HTML validation checks are unchanged and still absolute — those are not accessibility findings and cannot be acknowledged away. The manual generate-and-paste workflow is not gated at all.
A record of what you approved, and a worklist of what to revisit
- Acknowledgment trail. Every acknowledgment is recorded in a per-course
.a11y/acknowledgments.json— what page, which criteria, when, against which conformance level. An append-only log you can point to later. - Review queue. Pages that were borderline (or that a course audit flagged) land on a
.a11y/review-queue.jsonworklist, sorted worst-first so the closest calls are at the top. Two new tools work it:accessibility_review_queue— list the pages that deserve a human look (with links to free checkers like the WAVE browser extension and Microsoft Accessibility Insights), and mark one reviewed when you've handled it.audit_course_accessibility— re-scan every generated page of a course in one pass and refresh the worklist, so you can sweep a whole course before publishing.
No new credentials, no new setup — the gate and the queue are built into the publish tools you already use. The required conformance level is the ADA Title II baseline (WCAG 2.1 AA); making that configurable per institution is the next step (Phase 3).
Full diff: v1.9.0...v1.10.0
What's new in v1.9.0
The installer now connects Canvas Toolchain to any AI coding host you have — not just Claude.
Model-agnostic: wire up every supported host automatically
- One install, all your hosts. The installer detects which AI coding apps are on your machine and connects the Canvas Toolchain MCP server to each one, in that host's own config format and location: Claude Desktop, Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code, Kiro, and Antigravity. Previously it only wired Claude Desktop and Claude Code.
- You stay in control. The workflows screen shows a "Connect to these apps" checklist: detected hosts are pre-checked, undetected hosts are listed but unchecked, and you can override any of them before installing.
- Safe and repeatable. Each host's config is written in its native shape (JSON
mcpServers, VS Code'sserverswithtype: stdio, or Codex's TOML[mcp_servers]), existing entries are preserved, and re-running the installer never duplicates the entry.
Because the command-and-control server already speaks the cross-client MCP protocol, this was purely an installer-reach change — no server or tool changes. It's the first piece (sub-project A) of making the whole toolchain runnable from Codex, Gemini, and IDE hosts end to end.
Documentation
- New Feature overview and a full accessibility checks reference, both linked from the README.
Full diff: v1.8.2...v1.9.0
What's new in v1.8.2
A dependency-security release — no behavior changes, just a cleaner and safer dependency tree.
Security: removed an unmaintained YAML parser
- Replaced
gray-matterwith an in-house front-matter reader. Thegray-matterli...
v1.11.0
Canvas Toolchain Installer
What's new in v1.11.0
Accessibility Phase 3: your institution's policy becomes the anchor for every check, and two new tools join the kit — one to keep the policy current, one for optional deep checks via WAVE. Nothing changes until you opt in: with no policy configured, every check behaves exactly as it did in v1.10.x.
Your institution's accessibility policy, on file
- New tool
review_accessibility_policy— records your institution's accessibility policy links, the WCAG conformance level your courses must meet (default stays WCAG 2.1 AA, the ADA Title II baseline), and how often you want to be reminded to re-read the policy (default every 4 weeks). Call it withconfirm: trueafter re-reading the policy and it stamps the date; when the reminder comes due, a gentle nudge appears at the end of accessibility reports — it never blocks anything. - The required level moves the gate line, not the checks. Every page is still checked against the full WCAG 2.2 catalog; the policy level only decides which findings can hold a publish back. Set it to 2.2 AA when your institution adopts it and the gate follows — no other changes needed.
A preview of WCAG 3 (optional, informational only)
- Turn on
wcag3Advisoryin the policy and accessibility reports gain a short section mapping your findings to the corresponding WCAG 3 draft outcomes — a low-effort way to watch where the standard is heading. It is clearly labeled as draft material and can never block a publish.
Deep checks with WAVE (WebAIM)
- New tool
wave_deep_check— runs a publicly visible page through the paid WAVE API for a second opinion beyond the built-in engines. Spending is always deliberate: the first call only previews the cost (~2 credits) and runs nothing; call again withconfirm: trueto spend. Login-gated Canvas pages are refused before any credits are spent — for those, the report points you at the free WAVE browser extension instead.
Sturdier record-keeping at publish time
- The per-page
approvalsanda11yAcknowledgmentsmaps inpublish_courseare now keyed by each page's output file path. A bare filename still works as a convenience — but only when it matches exactly one page, so an acknowledgment can never silently apply to a page you didn't review. (#108)
Full diff: v1.10.1...v1.11.0
What's new in v1.10.1
A small polish release for the v1.10.0 accessibility publishing gate — clearer guidance when a publish is held back, and tidier record-keeping. No new tools, no setup changes.
Clearer instructions when a course publish is held back
- The block message now tells you exactly what to do. During a whole-course publish, a page can pass the up-front accessibility check but still get held at the final step — the page's HTML is re-checked after widget links are swapped for their Canvas URLs, and that final version is what students actually get. Previously the hold message pointed at an option that
publish_coursedoesn't accept. Now it spells out the exacta11yAcknowledgmentsentry to pass for that file — naming each failing criterion when the failures are clear-cut, or a simpletruefor near-misses — plusresume:trueso the publish continues right where it stopped. (#112)
Consistent record-keeping in the acknowledgment trail
- Every entry in
.a11y/acknowledgments.jsonnow identifies its page the same way — by the page's output file path. Previously, acknowledgments recorded for pages used the Canvas page title while those for assignments used the file path, so one course's audit trail mixed two labeling styles. Existing entries stay exactly as they are and remain valid; nothing to migrate. (#113)
Full diff: v1.10.0...v1.10.1
What's new in v1.10.0
Accessibility moves from advice to a gate — with you as the final decision-maker. Since v1.9.0 the toolchain has run a full WCAG 2.2 conformance check on every page and reported the results. This release makes that check matter at publish time: it can now hold a page back until you've seen the problems and decided to proceed anyway.
The two-tier publishing gate
When you publish to Canvas (publish_to_canvas, or a whole course with publish_course), each page's accessibility result decides what's required:
- Clean page — publishes exactly as before.
- Near-miss (borderline) — publishes once you acknowledge it, by passing
acknowledgeAccessibility: true. A quick "yes, I've seen it." - Clear failure — publishes once you acknowledge each failing criterion by name (e.g.
["1.4.3", "1.3.1"]). If the block message lists three failures, your acknowledgment has to name all three — so you can't wave past problems you haven't actually looked at.
You are always the final arbiter. Nothing is ever permanently blocked: the gate exists to make sure a failure is a decision, not an accident. The blocked message spells out exactly what to acknowledge and how. The FERPA scan and the Canvas-HTML validation checks are unchanged and still absolute — those are not accessibility findings and cannot be acknowledged away. The manual generate-and-paste workflow is not gated at all.
A record of what you approved, and a worklist of what to revisit
- Acknowledgment trail. Every acknowledgment is recorded in a per-course
.a11y/acknowledgments.json— what page, which criteria, when, against which conformance level. An append-only log you can point to later. - Review queue. Pages that were borderline (or that a course audit flagged) land on a
.a11y/review-queue.jsonworklist, sorted worst-first so the closest calls are at the top. Two new tools work it:accessibility_review_queue— list the pages that deserve a human look (with links to free checkers like the WAVE browser extension and Microsoft Accessibility Insights), and mark one reviewed when you've handled it.audit_course_accessibility— re-scan every generated page of a course in one pass and refresh the worklist, so you can sweep a whole course before publishing.
No new credentials, no new setup — the gate and the queue are built into the publish tools you already use. The required conformance level is the ADA Title II baseline (WCAG 2.1 AA); making that configurable per institution is the next step (Phase 3).
Full diff: v1.9.0...v1.10.0
What's new in v1.9.0
The installer now connects Canvas Toolchain to any AI coding host you have — not just Claude.
Model-agnostic: wire up every supported host automatically
- One install, all your hosts. The installer detects which AI coding apps are on your machine and connects the Canvas Toolchain MCP server to each one, in that host's own config format and location: Claude Desktop, Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code, Kiro, and Antigravity. Previously it only wired Claude Desktop and Claude Code.
- You stay in control. The workflows screen shows a "Connect to these apps" checklist: detected hosts are pre-checked, undetected hosts are listed but unchecked, and you can override any of them before installing.
- Safe and repeatable. Each host's config is written in its native shape (JSON
mcpServers, VS Code'sserverswithtype: stdio, or Codex's TOML[mcp_servers]), existing entries are preserved, and re-running the installer never duplicates the entry.
Because the command-and-control server already speaks the cross-client MCP protocol, this was purely an installer-reach change — no server or tool changes. It's the first piece (sub-project A) of making the whole toolchain runnable from Codex, Gemini, and IDE hosts end to end.
Documentation
- New Feature overview and a full accessibility checks reference, both linked from the README.
Full diff: v1.8.2...v1.9.0
What's new in v1.8.2
A dependency-security release — no behavior changes, just a cleaner and safer dependency tree.
Security: removed an unmaintained YAML parser
- Replaced
gray-matterwith an in-house front-matter reader. Thegray-matterlibrary was the only thing pulling in the old, unmaintainedjs-yamlv3, the source of two YAML advisories (including a quadratic-complexity denial-of-service, GHSA-h67p-54hq-rp68). It couldn't be patched in place, so it's gone — the toolchain now reads page/brief front matter with the maintainedyamlpackage it already uses everywhere else. Bothgray-matterandjs-yamlare fully removed from the dependency tree. Closes #103. - Patched a second high-severity
undiciadvisory. A separate copy ofundici(6.26.0, reached throughjuice→cheerio) was bumped in-place to the patched6.27.0.
npm audit now reports zero vulnerabilities. Behavior is unchanged and verified — full build, ~1,700 tests, and the cross-app integration smoke all green; the front-matter swap was done test-first with characterization tests locking the existing parse/serialize behavior.
Full diff: v1.8.1...v1.8.2
What's new in v1.8.1
A small installer fix for the Canvas host field on the credentials screen.
Forgiving Canvas host entry
- *...
v1.10.1
Canvas Toolchain Installer
What's new in v1.10.1
A small polish release for the v1.10.0 accessibility publishing gate — clearer guidance when a publish is held back, and tidier record-keeping. No new tools, no setup changes.
Clearer instructions when a course publish is held back
- The block message now tells you exactly what to do. During a whole-course publish, a page can pass the up-front accessibility check but still get held at the final step — the page's HTML is re-checked after widget links are swapped for their Canvas URLs, and that final version is what students actually get. Previously the hold message pointed at an option that
publish_coursedoesn't accept. Now it spells out the exacta11yAcknowledgmentsentry to pass for that file — naming each failing criterion when the failures are clear-cut, or a simpletruefor near-misses — plusresume:trueso the publish continues right where it stopped. (#112)
Consistent record-keeping in the acknowledgment trail
- Every entry in
.a11y/acknowledgments.jsonnow identifies its page the same way — by the page's output file path. Previously, acknowledgments recorded for pages used the Canvas page title while those for assignments used the file path, so one course's audit trail mixed two labeling styles. Existing entries stay exactly as they are and remain valid; nothing to migrate. (#113)
Full diff: v1.10.0...v1.10.1
What's new in v1.10.0
Accessibility moves from advice to a gate — with you as the final decision-maker. Since v1.9.0 the toolchain has run a full WCAG 2.2 conformance check on every page and reported the results. This release makes that check matter at publish time: it can now hold a page back until you've seen the problems and decided to proceed anyway.
The two-tier publishing gate
When you publish to Canvas (publish_to_canvas, or a whole course with publish_course), each page's accessibility result decides what's required:
- Clean page — publishes exactly as before.
- Near-miss (borderline) — publishes once you acknowledge it, by passing
acknowledgeAccessibility: true. A quick "yes, I've seen it." - Clear failure — publishes once you acknowledge each failing criterion by name (e.g.
["1.4.3", "1.3.1"]). If the block message lists three failures, your acknowledgment has to name all three — so you can't wave past problems you haven't actually looked at.
You are always the final arbiter. Nothing is ever permanently blocked: the gate exists to make sure a failure is a decision, not an accident. The blocked message spells out exactly what to acknowledge and how. The FERPA scan and the Canvas-HTML validation checks are unchanged and still absolute — those are not accessibility findings and cannot be acknowledged away. The manual generate-and-paste workflow is not gated at all.
A record of what you approved, and a worklist of what to revisit
- Acknowledgment trail. Every acknowledgment is recorded in a per-course
.a11y/acknowledgments.json— what page, which criteria, when, against which conformance level. An append-only log you can point to later. - Review queue. Pages that were borderline (or that a course audit flagged) land on a
.a11y/review-queue.jsonworklist, sorted worst-first so the closest calls are at the top. Two new tools work it:accessibility_review_queue— list the pages that deserve a human look (with links to free checkers like the WAVE browser extension and Microsoft Accessibility Insights), and mark one reviewed when you've handled it.audit_course_accessibility— re-scan every generated page of a course in one pass and refresh the worklist, so you can sweep a whole course before publishing.
No new credentials, no new setup — the gate and the queue are built into the publish tools you already use. The required conformance level is the ADA Title II baseline (WCAG 2.1 AA); making that configurable per institution is the next step (Phase 3).
Full diff: v1.9.0...v1.10.0
What's new in v1.9.0
The installer now connects Canvas Toolchain to any AI coding host you have — not just Claude.
Model-agnostic: wire up every supported host automatically
- One install, all your hosts. The installer detects which AI coding apps are on your machine and connects the Canvas Toolchain MCP server to each one, in that host's own config format and location: Claude Desktop, Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code, Kiro, and Antigravity. Previously it only wired Claude Desktop and Claude Code.
- You stay in control. The workflows screen shows a "Connect to these apps" checklist: detected hosts are pre-checked, undetected hosts are listed but unchecked, and you can override any of them before installing.
- Safe and repeatable. Each host's config is written in its native shape (JSON
mcpServers, VS Code'sserverswithtype: stdio, or Codex's TOML[mcp_servers]), existing entries are preserved, and re-running the installer never duplicates the entry.
Because the command-and-control server already speaks the cross-client MCP protocol, this was purely an installer-reach change — no server or tool changes. It's the first piece (sub-project A) of making the whole toolchain runnable from Codex, Gemini, and IDE hosts end to end.
Documentation
- New Feature overview and a full accessibility checks reference, both linked from the README.
Full diff: v1.8.2...v1.9.0
What's new in v1.8.2
A dependency-security release — no behavior changes, just a cleaner and safer dependency tree.
Security: removed an unmaintained YAML parser
- Replaced
gray-matterwith an in-house front-matter reader. Thegray-matterlibrary was the only thing pulling in the old, unmaintainedjs-yamlv3, the source of two YAML advisories (including a quadratic-complexity denial-of-service, GHSA-h67p-54hq-rp68). It couldn't be patched in place, so it's gone — the toolchain now reads page/brief front matter with the maintainedyamlpackage it already uses everywhere else. Bothgray-matterandjs-yamlare fully removed from the dependency tree. Closes #103. - Patched a second high-severity
undiciadvisory. A separate copy ofundici(6.26.0, reached throughjuice→cheerio) was bumped in-place to the patched6.27.0.
npm audit now reports zero vulnerabilities. Behavior is unchanged and verified — full build, ~1,700 tests, and the cross-app integration smoke all green; the front-matter swap was done test-first with characterization tests locking the existing parse/serialize behavior.
Full diff: v1.8.1...v1.8.2
What's new in v1.8.1
A small installer fix for the Canvas host field on the credentials screen.
Forgiving Canvas host entry
- A bare school name now works. Entering just
yourschoolis completed toyourschool.instructure.comautomatically, instead of failing validation withdial tcp: lookup yourschool: no such host. The field also accepts a pasted fullhttps://…URL (scheme and path are stripped) and tolerates trailing slashes, stray whitespace, and casing. Vanity Canvas domains that already contain a dot (e.g.canvas.yourschool.edu) pass through untouched. - Clearer field guidance. The placeholder and hint now read as an example rather than a pre-filled prefix, and spell out that a bare name works and a full URL can be pasted — so nobody types only the first label expecting
.instructure.comto be appended for them.
Normalization is applied to both credential validation and the written canvas-config.json, so the validated host always matches what's saved. Covered by unit tests (bare label, scheme/path strip, vanity domain, idempotence).
Dependency hygiene
- Bumped the transitive
undici(viacheerio) from 7.27.2 → 7.28.0 to clear a newly-disclosed high-severity advisory (GHSA-vmh5-mc38-953g). Non-breaking; full suite green. The deferredgray-matter/js-yamlmoderate advisory remains tracked as #103.
Full diff: v1.8.0...v1.8.1
What's new in v1.8.0
Completes the AI-Friendly Rubric System. The student-facing rewrite half shipped earlier as draft_student_rubric (turn a faculty rubric into plain-English, per-criterion guidance + worked examples + an LLM-paste .md). This release adds the missing half — getting the rubric out of Canvas in the first place — as a new Command & Control workflow tool.
Canvas Rubric Sync (review_canvas_rubric)
- Pull the rubric straight from Canvas. Give it a course and an assignment: it reads the rubric attached to that assignment, and falls back to a course-rubric pick-list when the assignment has none attached. No more copy-pasting a rubric out of Canvas to get started.
- See what changed since last time. It diffs the freshly-pulled rubric against your last student-facing rewrite, so you know exactly which criteria moved before you regenerate anything — with no extra bookkeeping files.
- Smart triage before you rewrite. A single review pass returns a verdict — **acceptable / needs-updat...
v1.10.0
Canvas Toolchain Installer
What's new in v1.10.0
Accessibility moves from advice to a gate — with you as the final decision-maker. Since v1.9.0 the toolchain has run a full WCAG 2.2 conformance check on every page and reported the results. This release makes that check matter at publish time: it can now hold a page back until you've seen the problems and decided to proceed anyway.
The two-tier publishing gate
When you publish to Canvas (publish_to_canvas, or a whole course with publish_course), each page's accessibility result decides what's required:
- Clean page — publishes exactly as before.
- Near-miss (borderline) — publishes once you acknowledge it, by passing
acknowledgeAccessibility: true. A quick "yes, I've seen it." - Clear failure — publishes once you acknowledge each failing criterion by name (e.g.
["1.4.3", "1.3.1"]). If the block message lists three failures, your acknowledgment has to name all three — so you can't wave past problems you haven't actually looked at.
You are always the final arbiter. Nothing is ever permanently blocked: the gate exists to make sure a failure is a decision, not an accident. The blocked message spells out exactly what to acknowledge and how. The FERPA scan and the Canvas-HTML validation checks are unchanged and still absolute — those are not accessibility findings and cannot be acknowledged away. The manual generate-and-paste workflow is not gated at all.
A record of what you approved, and a worklist of what to revisit
- Acknowledgment trail. Every acknowledgment is recorded in a per-course
.a11y/acknowledgments.json— what page, which criteria, when, against which conformance level. An append-only log you can point to later. - Review queue. Pages that were borderline (or that a course audit flagged) land on a
.a11y/review-queue.jsonworklist, sorted worst-first so the closest calls are at the top. Two new tools work it:accessibility_review_queue— list the pages that deserve a human look (with links to free checkers like the WAVE browser extension and Microsoft Accessibility Insights), and mark one reviewed when you've handled it.audit_course_accessibility— re-scan every generated page of a course in one pass and refresh the worklist, so you can sweep a whole course before publishing.
No new credentials, no new setup — the gate and the queue are built into the publish tools you already use. The required conformance level is the ADA Title II baseline (WCAG 2.1 AA); making that configurable per institution is the next step (Phase 3).
Full diff: v1.9.0...v1.10.0
What's new in v1.9.0
The installer now connects Canvas Toolchain to any AI coding host you have — not just Claude.
Model-agnostic: wire up every supported host automatically
- One install, all your hosts. The installer detects which AI coding apps are on your machine and connects the Canvas Toolchain MCP server to each one, in that host's own config format and location: Claude Desktop, Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code, Kiro, and Antigravity. Previously it only wired Claude Desktop and Claude Code.
- You stay in control. The workflows screen shows a "Connect to these apps" checklist: detected hosts are pre-checked, undetected hosts are listed but unchecked, and you can override any of them before installing.
- Safe and repeatable. Each host's config is written in its native shape (JSON
mcpServers, VS Code'sserverswithtype: stdio, or Codex's TOML[mcp_servers]), existing entries are preserved, and re-running the installer never duplicates the entry.
Because the command-and-control server already speaks the cross-client MCP protocol, this was purely an installer-reach change — no server or tool changes. It's the first piece (sub-project A) of making the whole toolchain runnable from Codex, Gemini, and IDE hosts end to end.
Documentation
- New Feature overview and a full accessibility checks reference, both linked from the README.
Full diff: v1.8.2...v1.9.0
What's new in v1.8.2
A dependency-security release — no behavior changes, just a cleaner and safer dependency tree.
Security: removed an unmaintained YAML parser
- Replaced
gray-matterwith an in-house front-matter reader. Thegray-matterlibrary was the only thing pulling in the old, unmaintainedjs-yamlv3, the source of two YAML advisories (including a quadratic-complexity denial-of-service, GHSA-h67p-54hq-rp68). It couldn't be patched in place, so it's gone — the toolchain now reads page/brief front matter with the maintainedyamlpackage it already uses everywhere else. Bothgray-matterandjs-yamlare fully removed from the dependency tree. Closes #103. - Patched a second high-severity
undiciadvisory. A separate copy ofundici(6.26.0, reached throughjuice→cheerio) was bumped in-place to the patched6.27.0.
npm audit now reports zero vulnerabilities. Behavior is unchanged and verified — full build, ~1,700 tests, and the cross-app integration smoke all green; the front-matter swap was done test-first with characterization tests locking the existing parse/serialize behavior.
Full diff: v1.8.1...v1.8.2
What's new in v1.8.1
A small installer fix for the Canvas host field on the credentials screen.
Forgiving Canvas host entry
- A bare school name now works. Entering just
yourschoolis completed toyourschool.instructure.comautomatically, instead of failing validation withdial tcp: lookup yourschool: no such host. The field also accepts a pasted fullhttps://…URL (scheme and path are stripped) and tolerates trailing slashes, stray whitespace, and casing. Vanity Canvas domains that already contain a dot (e.g.canvas.yourschool.edu) pass through untouched. - Clearer field guidance. The placeholder and hint now read as an example rather than a pre-filled prefix, and spell out that a bare name works and a full URL can be pasted — so nobody types only the first label expecting
.instructure.comto be appended for them.
Normalization is applied to both credential validation and the written canvas-config.json, so the validated host always matches what's saved. Covered by unit tests (bare label, scheme/path strip, vanity domain, idempotence).
Dependency hygiene
- Bumped the transitive
undici(viacheerio) from 7.27.2 → 7.28.0 to clear a newly-disclosed high-severity advisory (GHSA-vmh5-mc38-953g). Non-breaking; full suite green. The deferredgray-matter/js-yamlmoderate advisory remains tracked as #103.
Full diff: v1.8.0...v1.8.1
What's new in v1.8.0
Completes the AI-Friendly Rubric System. The student-facing rewrite half shipped earlier as draft_student_rubric (turn a faculty rubric into plain-English, per-criterion guidance + worked examples + an LLM-paste .md). This release adds the missing half — getting the rubric out of Canvas in the first place — as a new Command & Control workflow tool.
Canvas Rubric Sync (review_canvas_rubric)
- Pull the rubric straight from Canvas. Give it a course and an assignment: it reads the rubric attached to that assignment, and falls back to a course-rubric pick-list when the assignment has none attached. No more copy-pasting a rubric out of Canvas to get started.
- See what changed since last time. It diffs the freshly-pulled rubric against your last student-facing rewrite, so you know exactly which criteria moved before you regenerate anything — with no extra bookkeeping files.
- Smart triage before you rewrite. A single review pass returns a verdict — acceptable / needs-update / needs-review — with specific flagged criteria, and proposes a revised faculty rubric for your approval when one is warranted. The approved rubric then feeds the existing
draft_student_rubricunchanged. - Read-only and safe. The tool never writes to Canvas; you stay in control of every change (propose → you approve → commit).
Built as a coordinator workflow (not a new module), following the established Canvas-access and TDD patterns; hermetic tests with Canvas and the LLM injected. A second phase — auto-surfacing last term's student questions as an extra review signal — is designed and deferred pending a data check.
Known advisory (accepted, tracked)
npm audit reports 2 moderate advisories via the transitive js-yaml pulled in by the unmaintained gray-matter front-matter parser. This path only ever parses your own local course files (never untrusted input), so real-world risk is negligible. The proper fix — replacing gray-matter — is tracked as #103 and deferred from this release to avoid a risky last-minute breaking change.
Quality
Subagent-driven TDD with per-task spec + code-quality review and a final holistic review (which caught and fixed a faculty-block truncation bug on bold grade anchors, an empty-criteria guard, a file-read race, and a malformed-id filter). Full Command & Control suite green; both installer targets build cleanly.
Full diff: v1.7.0...v1.8.0
What's new in v1.7.0
...
v1.9.0
Canvas Toolchain Installer
What's new in v1.9.0
The installer now connects Canvas Toolchain to any AI coding host you have — not just Claude.
Model-agnostic: wire up every supported host automatically
- One install, all your hosts. The installer detects which AI coding apps are on your machine and connects the Canvas Toolchain MCP server to each one, in that host's own config format and location: Claude Desktop, Claude Code, Codex CLI, Gemini CLI, Cursor, VS Code, Kiro, and Antigravity. Previously it only wired Claude Desktop and Claude Code.
- You stay in control. The workflows screen shows a "Connect to these apps" checklist: detected hosts are pre-checked, undetected hosts are listed but unchecked, and you can override any of them before installing.
- Safe and repeatable. Each host's config is written in its native shape (JSON
mcpServers, VS Code'sserverswithtype: stdio, or Codex's TOML[mcp_servers]), existing entries are preserved, and re-running the installer never duplicates the entry.
Because the command-and-control server already speaks the cross-client MCP protocol, this was purely an installer-reach change — no server or tool changes. It's the first piece (sub-project A) of making the whole toolchain runnable from Codex, Gemini, and IDE hosts end to end.
Documentation
- New Feature overview and a full accessibility checks reference, both linked from the README.
Full diff: v1.8.2...v1.9.0
What's new in v1.8.2
A dependency-security release — no behavior changes, just a cleaner and safer dependency tree.
Security: removed an unmaintained YAML parser
- Replaced
gray-matterwith an in-house front-matter reader. Thegray-matterlibrary was the only thing pulling in the old, unmaintainedjs-yamlv3, the source of two YAML advisories (including a quadratic-complexity denial-of-service, GHSA-h67p-54hq-rp68). It couldn't be patched in place, so it's gone — the toolchain now reads page/brief front matter with the maintainedyamlpackage it already uses everywhere else. Bothgray-matterandjs-yamlare fully removed from the dependency tree. Closes #103. - Patched a second high-severity
undiciadvisory. A separate copy ofundici(6.26.0, reached throughjuice→cheerio) was bumped in-place to the patched6.27.0.
npm audit now reports zero vulnerabilities. Behavior is unchanged and verified — full build, ~1,700 tests, and the cross-app integration smoke all green; the front-matter swap was done test-first with characterization tests locking the existing parse/serialize behavior.
Full diff: v1.8.1...v1.8.2
What's new in v1.8.1
A small installer fix for the Canvas host field on the credentials screen.
Forgiving Canvas host entry
- A bare school name now works. Entering just
yourschoolis completed toyourschool.instructure.comautomatically, instead of failing validation withdial tcp: lookup yourschool: no such host. The field also accepts a pasted fullhttps://…URL (scheme and path are stripped) and tolerates trailing slashes, stray whitespace, and casing. Vanity Canvas domains that already contain a dot (e.g.canvas.yourschool.edu) pass through untouched. - Clearer field guidance. The placeholder and hint now read as an example rather than a pre-filled prefix, and spell out that a bare name works and a full URL can be pasted — so nobody types only the first label expecting
.instructure.comto be appended for them.
Normalization is applied to both credential validation and the written canvas-config.json, so the validated host always matches what's saved. Covered by unit tests (bare label, scheme/path strip, vanity domain, idempotence).
Dependency hygiene
- Bumped the transitive
undici(viacheerio) from 7.27.2 → 7.28.0 to clear a newly-disclosed high-severity advisory (GHSA-vmh5-mc38-953g). Non-breaking; full suite green. The deferredgray-matter/js-yamlmoderate advisory remains tracked as #103.
Full diff: v1.8.0...v1.8.1
What's new in v1.8.0
Completes the AI-Friendly Rubric System. The student-facing rewrite half shipped earlier as draft_student_rubric (turn a faculty rubric into plain-English, per-criterion guidance + worked examples + an LLM-paste .md). This release adds the missing half — getting the rubric out of Canvas in the first place — as a new Command & Control workflow tool.
Canvas Rubric Sync (review_canvas_rubric)
- Pull the rubric straight from Canvas. Give it a course and an assignment: it reads the rubric attached to that assignment, and falls back to a course-rubric pick-list when the assignment has none attached. No more copy-pasting a rubric out of Canvas to get started.
- See what changed since last time. It diffs the freshly-pulled rubric against your last student-facing rewrite, so you know exactly which criteria moved before you regenerate anything — with no extra bookkeeping files.
- Smart triage before you rewrite. A single review pass returns a verdict — acceptable / needs-update / needs-review — with specific flagged criteria, and proposes a revised faculty rubric for your approval when one is warranted. The approved rubric then feeds the existing
draft_student_rubricunchanged. - Read-only and safe. The tool never writes to Canvas; you stay in control of every change (propose → you approve → commit).
Built as a coordinator workflow (not a new module), following the established Canvas-access and TDD patterns; hermetic tests with Canvas and the LLM injected. A second phase — auto-surfacing last term's student questions as an extra review signal — is designed and deferred pending a data check.
Known advisory (accepted, tracked)
npm audit reports 2 moderate advisories via the transitive js-yaml pulled in by the unmaintained gray-matter front-matter parser. This path only ever parses your own local course files (never untrusted input), so real-world risk is negligible. The proper fix — replacing gray-matter — is tracked as #103 and deferred from this release to avoid a risky last-minute breaking change.
Quality
Subagent-driven TDD with per-task spec + code-quality review and a final holistic review (which caught and fixed a faculty-block truncation bug on bold grade anchors, an empty-criteria guard, a file-read race, and a malformed-id filter). Full Command & Control suite green; both installer targets build cleanly.
Full diff: v1.7.0...v1.8.0
What's new in v1.7.0
Two more capability modules land on the plug-in architecture, completing the term-management "module wave." Both follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft. Together with the existing Oral Assessment and Group Builder modules, they cover the full roster → groups → external-tool pipeline.
Roster & Identity Manager module (module-roster)
propose_roster/commit_roster/resolve_identity— turn a PeopleSoft export into a privacy-preserving course roster. The module matches PeopleSoft rows to live Canvas enrollments (by student number → email → login → name, in priority order), assigns each student a lifetime pseudonym persisted in a0600identity vault, normalizes majors via batched AI with an alias store, and emits a de-identifiedcanvas_id,pseudonym,majorroster CSV.- Privacy by construction. The vault is the only place the
canvas_id ↔ student_numberbridge lives; the roster output never carries names or emails.proposeis read-only and idempotent;commitis the single writer, with atomic writes and live-vault collision guards. - Resilient to thin tokens. A teacher-scoped Canvas token often withholds
login_id/sis_user_id; the matcher degrades gracefully and warns rather than failing.
PeerAssessment.com Export module (module-peerassessment)
build_peerassessment_import— turn a Canvas group set into the exact import CSV PeerAssessment.com expects (Team,Login ID,Email,First Name,Last Name,Student ID #). Canvas-first field sourcing, with the roster vault + PeopleSoft export filling the login/SIS columns Canvas withholds. AdryRunflag produces a full pre-upload validation report (incomplete students, ungrouped students, duplicate emails, multi-group students) without writing a file.- Import-only and FERPA-aware. The module produces an upload file only — it never writes Canvas or the vault, and grade round-trip is an explicit non-goal. PII is used transiently at build time; the only at-rest artifact is the import CSV the instructor uploads to a BSU-contracted, FERPA-approved vendor. Output is RFC-4180 escaped with a CSV formula-injection guard.
Dependency & supply-chain hygiene
- esbuild pinned via override to
^0.28.1(clears Dependabot #23/#24);action-gh-releasebumped to v3 for the Node 24 runtime; installer workflows moved to Go 1.25.npm auditreports zero vulnerabilities.
Quality
Both modules built with subagent-driven TDD and adversarial whole-implementation review (which caught and fixed a CSV formula-injection gap and a mult...
v1.8.2
Canvas Toolchain Installer
What's new in v1.8.2
A dependency-security release — no behavior changes, just a cleaner and safer dependency tree.
Security: removed an unmaintained YAML parser
- Replaced
gray-matterwith an in-house front-matter reader. Thegray-matterlibrary was the only thing pulling in the old, unmaintainedjs-yamlv3, the source of two YAML advisories (including a quadratic-complexity denial-of-service, GHSA-h67p-54hq-rp68). It couldn't be patched in place, so it's gone — the toolchain now reads page/brief front matter with the maintainedyamlpackage it already uses everywhere else. Bothgray-matterandjs-yamlare fully removed from the dependency tree. Closes #103. - Patched a second high-severity
undiciadvisory. A separate copy ofundici(6.26.0, reached throughjuice→cheerio) was bumped in-place to the patched6.27.0.
npm audit now reports zero vulnerabilities. Behavior is unchanged and verified — full build, ~1,700 tests, and the cross-app integration smoke all green; the front-matter swap was done test-first with characterization tests locking the existing parse/serialize behavior.
Full diff: v1.8.1...v1.8.2
What's new in v1.8.1
A small installer fix for the Canvas host field on the credentials screen.
Forgiving Canvas host entry
- A bare school name now works. Entering just
yourschoolis completed toyourschool.instructure.comautomatically, instead of failing validation withdial tcp: lookup yourschool: no such host. The field also accepts a pasted fullhttps://…URL (scheme and path are stripped) and tolerates trailing slashes, stray whitespace, and casing. Vanity Canvas domains that already contain a dot (e.g.canvas.yourschool.edu) pass through untouched. - Clearer field guidance. The placeholder and hint now read as an example rather than a pre-filled prefix, and spell out that a bare name works and a full URL can be pasted — so nobody types only the first label expecting
.instructure.comto be appended for them.
Normalization is applied to both credential validation and the written canvas-config.json, so the validated host always matches what's saved. Covered by unit tests (bare label, scheme/path strip, vanity domain, idempotence).
Dependency hygiene
- Bumped the transitive
undici(viacheerio) from 7.27.2 → 7.28.0 to clear a newly-disclosed high-severity advisory (GHSA-vmh5-mc38-953g). Non-breaking; full suite green. The deferredgray-matter/js-yamlmoderate advisory remains tracked as #103.
Full diff: v1.8.0...v1.8.1
What's new in v1.8.0
Completes the AI-Friendly Rubric System. The student-facing rewrite half shipped earlier as draft_student_rubric (turn a faculty rubric into plain-English, per-criterion guidance + worked examples + an LLM-paste .md). This release adds the missing half — getting the rubric out of Canvas in the first place — as a new Command & Control workflow tool.
Canvas Rubric Sync (review_canvas_rubric)
- Pull the rubric straight from Canvas. Give it a course and an assignment: it reads the rubric attached to that assignment, and falls back to a course-rubric pick-list when the assignment has none attached. No more copy-pasting a rubric out of Canvas to get started.
- See what changed since last time. It diffs the freshly-pulled rubric against your last student-facing rewrite, so you know exactly which criteria moved before you regenerate anything — with no extra bookkeeping files.
- Smart triage before you rewrite. A single review pass returns a verdict — acceptable / needs-update / needs-review — with specific flagged criteria, and proposes a revised faculty rubric for your approval when one is warranted. The approved rubric then feeds the existing
draft_student_rubricunchanged. - Read-only and safe. The tool never writes to Canvas; you stay in control of every change (propose → you approve → commit).
Built as a coordinator workflow (not a new module), following the established Canvas-access and TDD patterns; hermetic tests with Canvas and the LLM injected. A second phase — auto-surfacing last term's student questions as an extra review signal — is designed and deferred pending a data check.
Known advisory (accepted, tracked)
npm audit reports 2 moderate advisories via the transitive js-yaml pulled in by the unmaintained gray-matter front-matter parser. This path only ever parses your own local course files (never untrusted input), so real-world risk is negligible. The proper fix — replacing gray-matter — is tracked as #103 and deferred from this release to avoid a risky last-minute breaking change.
Quality
Subagent-driven TDD with per-task spec + code-quality review and a final holistic review (which caught and fixed a faculty-block truncation bug on bold grade anchors, an empty-criteria guard, a file-read race, and a malformed-id filter). Full Command & Control suite green; both installer targets build cleanly.
Full diff: v1.7.0...v1.8.0
What's new in v1.7.0
Two more capability modules land on the plug-in architecture, completing the term-management "module wave." Both follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft. Together with the existing Oral Assessment and Group Builder modules, they cover the full roster → groups → external-tool pipeline.
Roster & Identity Manager module (module-roster)
propose_roster/commit_roster/resolve_identity— turn a PeopleSoft export into a privacy-preserving course roster. The module matches PeopleSoft rows to live Canvas enrollments (by student number → email → login → name, in priority order), assigns each student a lifetime pseudonym persisted in a0600identity vault, normalizes majors via batched AI with an alias store, and emits a de-identifiedcanvas_id,pseudonym,majorroster CSV.- Privacy by construction. The vault is the only place the
canvas_id ↔ student_numberbridge lives; the roster output never carries names or emails.proposeis read-only and idempotent;commitis the single writer, with atomic writes and live-vault collision guards. - Resilient to thin tokens. A teacher-scoped Canvas token often withholds
login_id/sis_user_id; the matcher degrades gracefully and warns rather than failing.
PeerAssessment.com Export module (module-peerassessment)
build_peerassessment_import— turn a Canvas group set into the exact import CSV PeerAssessment.com expects (Team,Login ID,Email,First Name,Last Name,Student ID #). Canvas-first field sourcing, with the roster vault + PeopleSoft export filling the login/SIS columns Canvas withholds. AdryRunflag produces a full pre-upload validation report (incomplete students, ungrouped students, duplicate emails, multi-group students) without writing a file.- Import-only and FERPA-aware. The module produces an upload file only — it never writes Canvas or the vault, and grade round-trip is an explicit non-goal. PII is used transiently at build time; the only at-rest artifact is the import CSV the instructor uploads to a BSU-contracted, FERPA-approved vendor. Output is RFC-4180 escaped with a CSV formula-injection guard.
Dependency & supply-chain hygiene
- esbuild pinned via override to
^0.28.1(clears Dependabot #23/#24);action-gh-releasebumped to v3 for the Node 24 runtime; installer workflows moved to Go 1.25.npm auditreports zero vulnerabilities.
Quality
Both modules built with subagent-driven TDD and adversarial whole-implementation review (which caught and fixed a CSV formula-injection gap and a multi-group false-duplicate bug before release). The monorepo test suite now stands at ~1,698 tests, green, with the integration smoke test and both installer targets building cleanly.
Full diff: v1.6.0...v1.7.0
What's new in v1.6.0
Two new capability modules land on the plug-in architecture introduced in v1.5, plus a full user guide. Both modules follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft.
Oral Assessment module (#75)
design_oral_assessment— authoring-side design of oral / viva-style assessments. Give it either a finished brief or just a topic + learning goal, and it produces both a Canvas-ready CDSoral-assessmentpage and a faculty sidecar (rubric language, prompts, logistics). Carries the AI Assessment Scale callout like the rest of the assignment surface.- Capability, not a vendor. The boundary is the Oral Assessment capability; concrete tools are providers behind an adapter. Rhetorix Lab ships as the recommended provider #1 (flagged in the discovery catalog), with an optional
oral_assessment_launch_domainfor linking. Rhetorix is already LTI-native in Canvas, so this module is authoring-side — no extra plumbing or credentials required.
Group Creator / Maintainer module (#101)
create_groups/record_groups/propose_major_buckets— build balanced student project teams from a Canvas roster with a privacy-preserving identity model: groups key on the opaque Canvas user ID paired with a professor pseudonym (e.g.SU26-001) — the ...
v1.8.1
Canvas Toolchain Installer
What's new in v1.8.1
A small installer fix for the Canvas host field on the credentials screen.
Forgiving Canvas host entry
- A bare school name now works. Entering just
yourschoolis completed toyourschool.instructure.comautomatically, instead of failing validation withdial tcp: lookup yourschool: no such host. The field also accepts a pasted fullhttps://…URL (scheme and path are stripped) and tolerates trailing slashes, stray whitespace, and casing. Vanity Canvas domains that already contain a dot (e.g.canvas.yourschool.edu) pass through untouched. - Clearer field guidance. The placeholder and hint now read as an example rather than a pre-filled prefix, and spell out that a bare name works and a full URL can be pasted — so nobody types only the first label expecting
.instructure.comto be appended for them.
Normalization is applied to both credential validation and the written canvas-config.json, so the validated host always matches what's saved. Covered by unit tests (bare label, scheme/path strip, vanity domain, idempotence).
Dependency hygiene
- Bumped the transitive
undici(viacheerio) from 7.27.2 → 7.28.0 to clear a newly-disclosed high-severity advisory (GHSA-vmh5-mc38-953g). Non-breaking; full suite green. The deferredgray-matter/js-yamlmoderate advisory remains tracked as #103.
Full diff: v1.8.0...v1.8.1
What's new in v1.8.0
Completes the AI-Friendly Rubric System. The student-facing rewrite half shipped earlier as draft_student_rubric (turn a faculty rubric into plain-English, per-criterion guidance + worked examples + an LLM-paste .md). This release adds the missing half — getting the rubric out of Canvas in the first place — as a new Command & Control workflow tool.
Canvas Rubric Sync (review_canvas_rubric)
- Pull the rubric straight from Canvas. Give it a course and an assignment: it reads the rubric attached to that assignment, and falls back to a course-rubric pick-list when the assignment has none attached. No more copy-pasting a rubric out of Canvas to get started.
- See what changed since last time. It diffs the freshly-pulled rubric against your last student-facing rewrite, so you know exactly which criteria moved before you regenerate anything — with no extra bookkeeping files.
- Smart triage before you rewrite. A single review pass returns a verdict — acceptable / needs-update / needs-review — with specific flagged criteria, and proposes a revised faculty rubric for your approval when one is warranted. The approved rubric then feeds the existing
draft_student_rubricunchanged. - Read-only and safe. The tool never writes to Canvas; you stay in control of every change (propose → you approve → commit).
Built as a coordinator workflow (not a new module), following the established Canvas-access and TDD patterns; hermetic tests with Canvas and the LLM injected. A second phase — auto-surfacing last term's student questions as an extra review signal — is designed and deferred pending a data check.
Known advisory (accepted, tracked)
npm audit reports 2 moderate advisories via the transitive js-yaml pulled in by the unmaintained gray-matter front-matter parser. This path only ever parses your own local course files (never untrusted input), so real-world risk is negligible. The proper fix — replacing gray-matter — is tracked as #103 and deferred from this release to avoid a risky last-minute breaking change.
Quality
Subagent-driven TDD with per-task spec + code-quality review and a final holistic review (which caught and fixed a faculty-block truncation bug on bold grade anchors, an empty-criteria guard, a file-read race, and a malformed-id filter). Full Command & Control suite green; both installer targets build cleanly.
Full diff: v1.7.0...v1.8.0
What's new in v1.7.0
Two more capability modules land on the plug-in architecture, completing the term-management "module wave." Both follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft. Together with the existing Oral Assessment and Group Builder modules, they cover the full roster → groups → external-tool pipeline.
Roster & Identity Manager module (module-roster)
propose_roster/commit_roster/resolve_identity— turn a PeopleSoft export into a privacy-preserving course roster. The module matches PeopleSoft rows to live Canvas enrollments (by student number → email → login → name, in priority order), assigns each student a lifetime pseudonym persisted in a0600identity vault, normalizes majors via batched AI with an alias store, and emits a de-identifiedcanvas_id,pseudonym,majorroster CSV.- Privacy by construction. The vault is the only place the
canvas_id ↔ student_numberbridge lives; the roster output never carries names or emails.proposeis read-only and idempotent;commitis the single writer, with atomic writes and live-vault collision guards. - Resilient to thin tokens. A teacher-scoped Canvas token often withholds
login_id/sis_user_id; the matcher degrades gracefully and warns rather than failing.
PeerAssessment.com Export module (module-peerassessment)
build_peerassessment_import— turn a Canvas group set into the exact import CSV PeerAssessment.com expects (Team,Login ID,Email,First Name,Last Name,Student ID #). Canvas-first field sourcing, with the roster vault + PeopleSoft export filling the login/SIS columns Canvas withholds. AdryRunflag produces a full pre-upload validation report (incomplete students, ungrouped students, duplicate emails, multi-group students) without writing a file.- Import-only and FERPA-aware. The module produces an upload file only — it never writes Canvas or the vault, and grade round-trip is an explicit non-goal. PII is used transiently at build time; the only at-rest artifact is the import CSV the instructor uploads to a BSU-contracted, FERPA-approved vendor. Output is RFC-4180 escaped with a CSV formula-injection guard.
Dependency & supply-chain hygiene
- esbuild pinned via override to
^0.28.1(clears Dependabot #23/#24);action-gh-releasebumped to v3 for the Node 24 runtime; installer workflows moved to Go 1.25.npm auditreports zero vulnerabilities.
Quality
Both modules built with subagent-driven TDD and adversarial whole-implementation review (which caught and fixed a CSV formula-injection gap and a multi-group false-duplicate bug before release). The monorepo test suite now stands at ~1,698 tests, green, with the integration smoke test and both installer targets building cleanly.
Full diff: v1.6.0...v1.7.0
What's new in v1.6.0
Two new capability modules land on the plug-in architecture introduced in v1.5, plus a full user guide. Both modules follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft.
Oral Assessment module (#75)
design_oral_assessment— authoring-side design of oral / viva-style assessments. Give it either a finished brief or just a topic + learning goal, and it produces both a Canvas-ready CDSoral-assessmentpage and a faculty sidecar (rubric language, prompts, logistics). Carries the AI Assessment Scale callout like the rest of the assignment surface.- Capability, not a vendor. The boundary is the Oral Assessment capability; concrete tools are providers behind an adapter. Rhetorix Lab ships as the recommended provider #1 (flagged in the discovery catalog), with an optional
oral_assessment_launch_domainfor linking. Rhetorix is already LTI-native in Canvas, so this module is authoring-side — no extra plumbing or credentials required.
Group Creator / Maintainer module (#101)
create_groups/record_groups/propose_major_buckets— build balanced student project teams from a Canvas roster with a privacy-preserving identity model: groups key on the opaque Canvas user ID paired with a professor pseudonym (e.g.SU26-001) — the tool never reads or emits student names or emails.- Six formation strategies — random, alphabetical, performance (heterogeneous / homogeneous), accomplishment-weighted, and major-diversity — layered with cross-cutting constraints: a soft no-repeat-pairing "maintainer" (per-course pairing history) and group-size balancing, resolved by a seeded score-and-optimize engine.
- Major-diversity proposes archetype buckets (technical / quantitative / creative / business / other) for the professor to review and persist, rather than guessing silently.
- Outputs a CSV + markdown report with diagnostics, and can optionally push the result straight to a Canvas Group Set.
Documentation
- User Guide & tutorial — a narrative "start here" guide with an end-to-end walkthrough plus a task-by-task command catalog (what each tool does, how it works, and why you'd reach for it) covering ~120 MCP tools.
Quality
Both modules built with subagent-driven TDD and adversarial whole-implementation review. The monorepo test suite now stands at ~1,610 tests, green, with the integration smoke test and both installer targets building cleanly.
Full diff: v1.5.2...v1.6.0
What's new in v1.5.2
The biggest release since the toolchain shipped — 230+ commits since v1....
v1.8.0
Canvas Toolchain Installer
What's new in v1.8.0
Completes the AI-Friendly Rubric System. The student-facing rewrite half shipped earlier as draft_student_rubric (turn a faculty rubric into plain-English, per-criterion guidance + worked examples + an LLM-paste .md). This release adds the missing half — getting the rubric out of Canvas in the first place — as a new Command & Control workflow tool.
Canvas Rubric Sync (review_canvas_rubric)
- Pull the rubric straight from Canvas. Give it a course and an assignment: it reads the rubric attached to that assignment, and falls back to a course-rubric pick-list when the assignment has none attached. No more copy-pasting a rubric out of Canvas to get started.
- See what changed since last time. It diffs the freshly-pulled rubric against your last student-facing rewrite, so you know exactly which criteria moved before you regenerate anything — with no extra bookkeeping files.
- Smart triage before you rewrite. A single review pass returns a verdict — acceptable / needs-update / needs-review — with specific flagged criteria, and proposes a revised faculty rubric for your approval when one is warranted. The approved rubric then feeds the existing
draft_student_rubricunchanged. - Read-only and safe. The tool never writes to Canvas; you stay in control of every change (propose → you approve → commit).
Built as a coordinator workflow (not a new module), following the established Canvas-access and TDD patterns; hermetic tests with Canvas and the LLM injected. A second phase — auto-surfacing last term's student questions as an extra review signal — is designed and deferred pending a data check.
Known advisory (accepted, tracked)
npm audit reports 2 moderate advisories via the transitive js-yaml pulled in by the unmaintained gray-matter front-matter parser. This path only ever parses your own local course files (never untrusted input), so real-world risk is negligible. The proper fix — replacing gray-matter — is tracked as #103 and deferred from this release to avoid a risky last-minute breaking change.
Quality
Subagent-driven TDD with per-task spec + code-quality review and a final holistic review (which caught and fixed a faculty-block truncation bug on bold grade anchors, an empty-criteria guard, a file-read race, and a malformed-id filter). Full Command & Control suite green; both installer targets build cleanly.
Full diff: v1.7.0...v1.8.0
What's new in v1.7.0
Two more capability modules land on the plug-in architecture, completing the term-management "module wave." Both follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft. Together with the existing Oral Assessment and Group Builder modules, they cover the full roster → groups → external-tool pipeline.
Roster & Identity Manager module (module-roster)
propose_roster/commit_roster/resolve_identity— turn a PeopleSoft export into a privacy-preserving course roster. The module matches PeopleSoft rows to live Canvas enrollments (by student number → email → login → name, in priority order), assigns each student a lifetime pseudonym persisted in a0600identity vault, normalizes majors via batched AI with an alias store, and emits a de-identifiedcanvas_id,pseudonym,majorroster CSV.- Privacy by construction. The vault is the only place the
canvas_id ↔ student_numberbridge lives; the roster output never carries names or emails.proposeis read-only and idempotent;commitis the single writer, with atomic writes and live-vault collision guards. - Resilient to thin tokens. A teacher-scoped Canvas token often withholds
login_id/sis_user_id; the matcher degrades gracefully and warns rather than failing.
PeerAssessment.com Export module (module-peerassessment)
build_peerassessment_import— turn a Canvas group set into the exact import CSV PeerAssessment.com expects (Team,Login ID,Email,First Name,Last Name,Student ID #). Canvas-first field sourcing, with the roster vault + PeopleSoft export filling the login/SIS columns Canvas withholds. AdryRunflag produces a full pre-upload validation report (incomplete students, ungrouped students, duplicate emails, multi-group students) without writing a file.- Import-only and FERPA-aware. The module produces an upload file only — it never writes Canvas or the vault, and grade round-trip is an explicit non-goal. PII is used transiently at build time; the only at-rest artifact is the import CSV the instructor uploads to a BSU-contracted, FERPA-approved vendor. Output is RFC-4180 escaped with a CSV formula-injection guard.
Dependency & supply-chain hygiene
- esbuild pinned via override to
^0.28.1(clears Dependabot #23/#24);action-gh-releasebumped to v3 for the Node 24 runtime; installer workflows moved to Go 1.25.npm auditreports zero vulnerabilities.
Quality
Both modules built with subagent-driven TDD and adversarial whole-implementation review (which caught and fixed a CSV formula-injection gap and a multi-group false-duplicate bug before release). The monorepo test suite now stands at ~1,698 tests, green, with the integration smoke test and both installer targets building cleanly.
Full diff: v1.6.0...v1.7.0
What's new in v1.6.0
Two new capability modules land on the plug-in architecture introduced in v1.5, plus a full user guide. Both modules follow the established CanvasToolchainModule contract, are enabled at config-time via ~/.command-and-control/modules.json (no reinstall), and load fail-soft.
Oral Assessment module (#75)
design_oral_assessment— authoring-side design of oral / viva-style assessments. Give it either a finished brief or just a topic + learning goal, and it produces both a Canvas-ready CDSoral-assessmentpage and a faculty sidecar (rubric language, prompts, logistics). Carries the AI Assessment Scale callout like the rest of the assignment surface.- Capability, not a vendor. The boundary is the Oral Assessment capability; concrete tools are providers behind an adapter. Rhetorix Lab ships as the recommended provider #1 (flagged in the discovery catalog), with an optional
oral_assessment_launch_domainfor linking. Rhetorix is already LTI-native in Canvas, so this module is authoring-side — no extra plumbing or credentials required.
Group Creator / Maintainer module (#101)
create_groups/record_groups/propose_major_buckets— build balanced student project teams from a Canvas roster with a privacy-preserving identity model: groups key on the opaque Canvas user ID paired with a professor pseudonym (e.g.SU26-001) — the tool never reads or emits student names or emails.- Six formation strategies — random, alphabetical, performance (heterogeneous / homogeneous), accomplishment-weighted, and major-diversity — layered with cross-cutting constraints: a soft no-repeat-pairing "maintainer" (per-course pairing history) and group-size balancing, resolved by a seeded score-and-optimize engine.
- Major-diversity proposes archetype buckets (technical / quantitative / creative / business / other) for the professor to review and persist, rather than guessing silently.
- Outputs a CSV + markdown report with diagnostics, and can optionally push the result straight to a Canvas Group Set.
Documentation
- User Guide & tutorial — a narrative "start here" guide with an end-to-end walkthrough plus a task-by-task command catalog (what each tool does, how it works, and why you'd reach for it) covering ~120 MCP tools.
Quality
Both modules built with subagent-driven TDD and adversarial whole-implementation review. The monorepo test suite now stands at ~1,610 tests, green, with the integration smoke test and both installer targets building cleanly.
Full diff: v1.5.2...v1.6.0
What's new in v1.5.2
The biggest release since the toolchain shipped — 230+ commits since v1.2.0 completing the v1.x roadmap and laying the v2.0 platform foundations. This is the "build complete" milestone: the toolchain now does what it set out to do, end to end.
v1.5.2 is the first-public-release polish pass over v1.5.1: MIT license included, production dependency audit now clean (the optional
transformers-jsembedding fallback is no longer installed by default —setup_lecture_answersexplains how to add it), a general CI workflow enforcing the full TypeScript suite on every push/PR, and repo security hardening (secret scanning, push protection, Dependabot).
Plug-in module architecture (the 2.0 foundation)
- Modules + providers (#78) — capabilities are now opt-in modules, enabled at config-time via
~/.command-and-control/modules.json(no reinstall). A module is its own npm package exposing aCanvasToolchainModulecontract; within it, concrete backends are providers behind an adapter. First module: Lecture Video (module-video) with Panopto as provider #1 — the boundary is the Video capability, not Panopto, so Teams/Zoom/Meet/YouTube become ~one-file additions. Panopto code was fully extracted out of the core packages; C&C loads modules fail-soft (a broken module is skipped, never crashes the host). set_module_enabled/list_modules(#94) — toggle modules post-install without hand-editing the manifest.
Institutional intelligence
- Post-install tool discovery (#76) —
discover_toolsruns a best-effort Canvas scan (account → per-course → self-report, paginated), matches findings against a cur...