diff --git a/CHANGELOG.md b/CHANGELOG.md index 65830d4..1073ede 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,35 @@ ### Changed +- **The extension page and legal pages describe 0.9.0, the next Chrome Web + Store release**, and say where 0.8.2, on the store today, differs. Patches + (0.8.3 to 0.8.9) are test releases that do not go to the store, so + `extensionVersions.next` is now 0.9.0, not 0.8.4. + - Student flags: the extension no longer hides Toddle's own flags. A + teacher can conceal them for a shared screen with the free switch, and + "Show flags" in the sidebar shows one student's. The wording is + "conceal" and "flag visibility", said once in `flags` + (`src/data/legal.ts`); a test fails on "hide flags" on the extension + page, the home page and in llms.txt. The sidebar asks Toddle for a + student's flags each time it opens. The value on Toddle's site is + `tee-blur-flags` (`gbx-hide-flags` in 0.8.2). + - The rebuild: the flag switch, the student sidebar and the home page's + additions run in the extension's isolated world, in closed shadow roots + (product page, Security page, llms.txt). The Security page adds the home + page channel's limit. + - The student sidebar: today's timetable as its own part, the student's + email, a class's teachers to email at once, and stepping aside in + Toddle's admin portal. My classes switches on and off at once. + - For schools: the Admin console, Group Policy, Intune and macOS steps, + the organisation key pasted in once by each teacher, and allowing + `licences.nyuchi.dev`, summarised on the extension page; the full guide + on request. A link to the help centre's "How to use" collection. + - The data schema (the extension's `docs/data-schema.md`) is described on + the data handling page and the extension page, available on request. + - Data handling: the licence server keeps a SHA-256 of each key, never + the key itself, and the school's email domains for an organisation key. + - The second security review was of 0.8.4, a test release; its fixes are + in 0.9.0. - **The privacy policy rests on two laws: Zimbabwe's Cyber and Data Protection Act [Chapter 12:07] and the EU and UK GDPR**, applied to everyone. A new "The law we follow" section names POTRAZ as Zimbabwe's regulator, says diff --git a/astro.config.mjs b/astro.config.mjs index e90682d..a9b8591 100644 --- a/astro.config.mjs +++ b/astro.config.mjs @@ -35,7 +35,8 @@ export default defineConfig({ */ serialize(item) { item.url = item.url.replace(/(.+)\/$/, "$1"); - item.lastmod = new Date(); + // The sitemap item takes an ISO 8601 string, not a Date. + item.lastmod = new Date().toISOString(); return item; }, }), diff --git a/package-lock.json b/package-lock.json index c71d146..94891ba 100644 --- a/package-lock.json +++ b/package-lock.json @@ -7313,9 +7313,9 @@ } }, "node_modules/source-map-js": { - "version": "1.2.1", - "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.1.tgz", - "integrity": "sha512-UXWMKhLOwVKb728IUtQPXxfYU+usdybtUrK/8uGE8CQMvrhOpwvzDBwj0QhSL7MQc7vIsISBG8VQ8+IDQxpfQA==", + "version": "1.2.2", + "resolved": "https://registry.npmjs.org/source-map-js/-/source-map-js-1.2.2.tgz", + "integrity": "sha512-KGj/8Y43x35aZVDtt+J4mK1hoLGHULMYfSkODJNQjNDC3oW1PqPoxMwo0pLUsWM/UEGzON/NxeHywEfNXNP3Vw==", "license": "BSD-3-Clause", "engines": { "node": ">=0.10.0" diff --git a/public/llms.txt b/public/llms.txt index 6d7b550..334a496 100644 --- a/public/llms.txt +++ b/public/llms.txt @@ -17,25 +17,36 @@ community-based platforms. Nyuchi Web Services is its development division. score-based rubrics, single-point rubrics, checklists, scores, comments, grade scales, learning goals — into one column per standard, criterion or item, so a teacher sees the whole class at once instead of opening a side - panel per student. It also adds a switch that hides Toddle's student flags - across the product, so a gradebook can be projected or screen-shared without - a flag being visible. From version 0.8.4, flags are shown as Toddle shows - them, and a staff member can hide them everywhere with the switch, which is - free; an eye button then shows one student's flags. Versions before 0.8.4 - hid them by default. It hides flags, not names. Free: the flag switch and - a "My classes" filter on the Toddle home page. With a licence: the - per-criterion gradebook columns, CSV export, primary teacher names, the - Attendance dashboard's details, and the student sidebar. The sidebar - (since version 0.8.2) works anywhere a student appears in Toddle (class - pages, the Attendance dashboard's Periods, Students and Excusals tabs, name links, - gradebook student cells) and shows a photo, grade, age and class of, Student - Group, room number, homeroom advisor, contacts with relationship, phone and - email, a "Now" card (current attendance code, block, class, room and - timetabled teacher), today's daily attendance code, and the student's - classes in Today and All tabs. Clicking a class opens a class view with its - current block, primary teacher, parent course, room and every teacher with - their display title and email. Message buttons open Toddle's own chat; the - extension sends no message itself. On the Attendance dashboard's Students + panel per student. It also gives teachers control of flag visibility on a + shared screen. From version 0.9.0 (the next Chrome Web Store release), + the extension no longer hides Toddle's own student flags; a teacher can + conceal them with one free switch, in Toddle's header or the extension's + menu, so a gradebook can be projected or screen-shared without what a flag + says being readable from across the room. In the student sidebar, "Show flags" shows + one student's flags. Concealing is a screen, not a lock: a concealed flag + can still show that a student has a flag. In version 0.8.2, on the store + today, flags are hidden from the start and the switch shows or hides them. + It conceals flags, not names. Free: the flag switch and a "My classes" + filter on the Toddle home page. With a licence (US$5 a year for one + teacher, US$149.99 a year for a school's email domain): the per-criterion + gradebook columns, CSV export, primary teacher names, the Attendance + dashboard's details, and the student sidebar. The sidebar works anywhere a + student appears in Toddle (class pages, the Attendance dashboard's Periods, + Students and Excusals tabs, name links, gradebook student cells), except + in School setup, Toddle's admin portal, where it steps aside. It shows a + photo, grade, age and class of, the student's email (click to copy), + Student Group, room number, homeroom advisor, contacts with relationship, + phone and email, a "Now" card (current attendance code, block, class, room + and timetabled teacher), and today's timetable as its own part, which + shows today's periods, "No classes today", or "Couldn't load timetable" + with a Retry button, without holding up the rest of the panel. Clicking a + class opens a class view with its current block, primary teacher, parent + course, room and every teacher with their display title and email; the + teachers can be emailed together. Message buttons open Toddle's own chat; + the extension sends no message itself. From version 0.9.0 the flag switch, + the student sidebar and the home page's additions run in the extension's + own isolated world, drawn in closed shadow roots that no script on + Toddle's page can read or click into. On the Attendance dashboard's Students tab, each student's year group and current class and teacher appear under their name, and the current block's column is outlined. It reads Toddle in the teacher's own browser, for the teacher at the screen, through an exact @@ -56,8 +67,8 @@ community-based platforms. Nyuchi Web Services is its development division. email domain), which is compared with the signed-in Toddle account inside the browser only. An organisation licence is one key for the school's email domain: anyone signed in to Toddle with an address at that domain is - covered. Unless flags are hidden, the sidebar asks Toddle for a student's - flags each time it opens, and keeps them only while it is open. Apart + covered. The sidebar asks Toddle for a student's flags each time it opens, + and keeps them only while it is open. Apart from Toddle, it has two outside connections, neither carrying Toddle data. (1) Opt-in feedback: the toolbar menu's "Send feedback" form, which, only when the person presses Send, sends what they typed (topic, message, and an email only if they @@ -76,11 +87,21 @@ community-based platforms. Nyuchi Web Services is its development division. licence key if there is one, the result of the last check for cancelled keys, and the email of the Toddle account last seen signed in (to check who a licence is for); and, in Toddle's own site storage, a copy of the - switches, whether flags are hidden, the My classes choice and the academic - year Toddle is showing. No student data is stored: what it reads stays in + switches, whether flags are concealed, the My classes choice and the + academic year Toddle is showing. No student data is stored: what it reads stays in the tab's memory until the tab is closed or reloaded. Rubric levels and descriptors are read from whatever a school has configured in Toddle; none - are defined in the extension. Security: https://learning.nyuchi.com/legal/security + are defined in the extension. Every query, stored value and request is + listed field by field in the extension's data schema, which is checked + against its code on every change; schools can ask privacy@nyuchi.com for + a copy. Schools deploy it from the Chrome Web Store by extension ID, with + a Google Admin console force-install (or Group Policy, Intune or a macOS + profile); an organisation key is pasted in once by each teacher, since it + cannot be pushed by policy. Teachers get each minor release (0.9.0 next) + from the Chrome Web Store; patch releases between them are for testing + and do not go to the store. Help: + https://support.nyuchi.com/en/collections/19764027-how-to-use-the-toddle-enhancement-extension + Security: https://learning.nyuchi.com/legal/security ## Where the learning content went @@ -138,8 +159,8 @@ division of Nyuchi Africa (Private) Limited, Harare, Zimbabwe. end-to-end network recorder that fails on any non-Toddle request, every release gated on them), two adversarial reviews (1 October 2026: two High, one Medium and several Low findings, all fixed in 0.8.2 with tests; - 6 October 2026: two Medium and two Low findings in the code for 0.8.4, all - fixed before it is published), and the residual limits (scripts Toddle + 6 October 2026: two Medium and two Low findings in the code for 0.8.4, a + test release, all fixed there and in 0.9.0), and the residual limits (scripts Toddle itself loads share the page and the teacher's access regardless of any extension; Toddle's pages send no Content-Security-Policy; a script already listening in Toddle's page can replay the extension's per-load diff --git a/src/data/legal.ts b/src/data/legal.ts index 29b02b4..d583e10 100644 --- a/src/data/legal.ts +++ b/src/data/legal.ts @@ -87,8 +87,8 @@ export const pricing = [ includes: [ "Every assessment tool expanded into per-criterion columns", "CSV export", - "The student sidebar, with where they are now and today's classes", - "The class view, and message buttons into Toddle's chat", + "The student sidebar, with where they are now and today's timetable", + "The class view, a class's teachers to email at once, and message buttons into Toddle's chat", "Primary teacher names, and the Attendance dashboard's Now line", ], }, @@ -107,28 +107,57 @@ export const pricing = [ ] as const; /** - * Which versions of the extension the legal pages describe. `current` is what - * teachers have from the Chrome Web Store (the v0.8.3 tag carries the same - * code). `next` is the release under Unreleased in the extension's changelog: - * reviewed, not yet published. Claims that differ between the two say "from - * version 0.8.4", so they stay true on both sides of the release. When `next` - * ships, move it to `current` and drop the "before" wording. + * Which versions of the extension the legal pages describe. + * + * How the extension is released: patches (0.8.3, 0.8.4, …) are GitHub + * releases, for testing, and never go to the Chrome Web Store; each minor + * (0.9.0, …) is released from the extension's `main` branch and published to + * the store. Teachers get minors. + * + * `current` is what teachers have from the Chrome Web Store (the v0.8.3 tag + * carries the same code). `next` is the next minor: everything under + * Unreleased in the extension's changelog, reviewed, already in the patch + * releases up to `latestPatch`, and not yet on the store. Claims that differ + * between the two say "from version 0.9.0" and say what `current` does, so + * they stay true on both sides of the release. When `next` ships, move it to + * `current` and drop the "before" wording. */ export const extensionVersions = { current: "0.8.2", sameCodeAs: "0.8.3", - next: "0.8.4", + next: "0.9.0", + /** The newest patch release (GitHub only, for testing). */ + latestPatch: "0.8.9", /** The oldest version security reports are accepted for. */ supportedFrom: "0.8.2", } as const; -const { next } = extensionVersions; +const { current, next } = extensionVersions; + +/** + * Student flags, said once. From 0.9.0 the extension never hides Toddle's own + * flags: a teacher can conceal them for a shared screen. The wording is + * "conceal" and "flag visibility", never "hide", and it promises no more than + * the extension does: how a concealed flag looks is still being refined, so + * this says only that what a flag says cannot be read from across a room. + * Checked against the extension's SECURITY.md and docs/data-schema.md. + */ +export const flags = { + summary: + "The extension never hides Toddle's own student flags: they show as Toddle shows them. When your screen is shown to a class, a parent or a visitor, one free switch conceals them across Toddle, so what a flag says cannot be read from across the room.", + reveal: + 'In the student sidebar, "Show flags" shows one student\'s flags when you need them.', + limit: + "Concealing is a screen, not a lock. A concealed flag can still show that a student has a flag. Concealing changes only what is drawn on the screen, never Toddle's data, and does not stop anyone at the computer opening a student's flags in Toddle.", + before: `In version ${current}, on the Chrome Web Store today, the extension hides flags from the start, and the switch shows or hides them.`, +} as const; /** * What the extension does with data. Each of these is a claim that can be - * checked against the source (the extension's docs/toddle-data-fields.md is - * the full schema, checked against its code), and each maps to an answer on - * the Chrome Web Store privacy form. + * checked against the source (the extension's docs/data-schema.md, formerly + * docs/toddle-data-fields.md, is the full schema, checked against its code on + * every change), and each maps to an answer on the Chrome Web Store privacy + * form. */ export const extensionDataFacts = [ { @@ -144,12 +173,12 @@ export const extensionDataFacts = [ { claim: "What it reads, feature by feature.", detail: - "Toddle answers with what the signed-in teacher's own account may see, and no more. The gradebook tools, when a teacher expands an assessment: its assessment tools as Toddle defines them (rubric criteria, descriptors and levels, grade scales and their colours, checklist items, scores, standards and learning goals), and each assigned student's name, email, student ID, submission status and results, including written responses and comments. No descriptor or level is written in the extension. The home page: each class's staff, to show its primary teacher and the My classes filter. A student's profile page: the teachers of each of the student's classes. The Attendance dashboard: each student's year group and the names of the periods, from Toddle's own request, and the primary teacher of the class each student is in now, for the “Now: class · teacher” line. The student sidebar, when a teacher opens a student or a class: the student's name, photo, year group and age (the date of birth is used to work out the age and is never shown), email, student ID and enrolment date; their family accounts and contacts, with names, relationships, phone numbers and emails; their homeroom advisor; the school's additional profile fields, of which only Student Group and Room number are ever shown; today's timetable and attendance marks; their active flags, when flags are shown; and each class's teachers, with their display titles and emails.", + "Toddle answers with what the signed-in teacher's own account may see, and no more. The gradebook tools, when a teacher expands an assessment: its assessment tools as Toddle defines them (rubric criteria, descriptors and levels, grade scales and their colours, checklist items, scores, standards and learning goals), and each assigned student's name, email, student ID, submission status and results, including written responses and comments. No descriptor or level is written in the extension. The home page: each class's staff, to show its primary teacher and the My classes filter. A student's profile page: the teachers of each of the student's classes. The Attendance dashboard: each student's year group and the names of the periods, from Toddle's own request, and the primary teacher of the class each student is in now, for the “Now: class · teacher” line. The student sidebar, when a teacher opens a student or a class: the student's name, photo, year group and age (the date of birth is used to work out the age and is never shown), email, student ID and enrolment date; their family accounts and contacts, with names, relationships, phone numbers and emails; their homeroom advisor; the school's additional profile fields, of which only Student Group and Room number are ever shown; today's timetable and attendance marks; their active flags (see the next point); and each class's teachers, with their display titles and emails.", }, { claim: - "Student flags: shown as Toddle shows them, hidden with one free switch.", - detail: `From version ${next}, flags are shown as Toddle shows them. A staff member can hide them everywhere in Toddle with the switch, in Toddle's top bar or the extension's menu; the eye button then shows one student's flags. Versions before ${next} hid flags by default. Unless flags are hidden, the sidebar asks Toddle for a student's active flags each time it opens; while they are hidden, it asks only when someone presses the eye button. It keeps them only while that student's sidebar is open. Hiding flags changes only what is drawn on the screen, never Toddle's data. The flag switch is free and always will be.`, + "Student flags: Toddle's own are never hidden, and a teacher can conceal them for a shared screen.", + detail: `From version ${next}, the extension no longer hides Toddle's own student flags: they show as Toddle shows them, including in Toddle's student popover, with their links and documents. A teacher can choose to conceal flags, for a screen a class or a visitor can see, with the free flag switch in Toddle's top bar or the extension's menu. It is off until they switch it on; a teacher who had chosen to hide flags in an earlier version keeps that choice, as concealing. What a concealed flag says cannot be read from across a room, though it can still show that a student has a flag. ${flags.reveal} The sidebar asks Toddle for a student's active flags each time it opens, and keeps them only while that student's sidebar is open. Concealing changes only what is drawn on the screen, never Toddle's data. ${flags.before} In that version, while flags are hidden, the sidebar asks for a student's flags only when someone presses its eye button. The flag switch is free and always will be.`, }, { claim: "Your Toddle sign-in stays with Toddle.", @@ -173,7 +202,7 @@ export const extensionDataFacts = [ }, { claim: "What it stores: settings and licence details, and no student data.", - detail: `In Chrome's storage for the extension, on your device: your switches (the extension on or off, student flags, the student sidebar, My classes, primary teacher names, gradebook tools, and student details on the Attendance dashboard); your licence key, if you entered one; the result of the last check for cancelled keys (whether your key is on the list, the list's date and when the check was made, never the list itself); and the email address of the Toddle account last seen signed in, with the time, so the extension can check who a licence is for. That email is read on every Toddle page, with or without a licence key, and stays on the device. In the browser's storage for Toddle's own site: tee-settings, a copy of your switches and of which features the licence allows (no key and no email); gbx-hide-flags, whether flags are hidden, so they are hidden before the page is drawn; tee-course-view, whether you chose My classes in the home page filter; and tee-academic-year, the number of the academic year Toddle last asked for. Nothing it reads about students, classes, results or attendance is ever written to storage. Versions before ${next} have three switches: student flags, the student sidebar and primary teacher names.`, + detail: `In Chrome's storage for the extension, on your device: your switches (the extension on or off, student flags, the student sidebar, My classes, primary teacher names, gradebook tools, and student details on the Attendance dashboard); your licence key, if you entered one; the result of the last check for cancelled keys (whether your key is on the list, the list's date and when the check was made, never the list itself); and the email address of the Toddle account last seen signed in, with the time, so the extension can check who a licence is for. That email is read on every Toddle page, with or without a licence key, and stays on the device. In the browser's storage for Toddle's own site: tee-settings, a copy of your switches and of which features the licence allows (no key and no email); tee-blur-flags (gbx-hide-flags in version ${current}), whether flags are concealed, so they are concealed before the page is drawn; tee-course-view, whether you chose My classes in the home page filter; and tee-academic-year, the number of the academic year Toddle last asked for. Nothing it reads about students, classes, results or attendance is ever written to storage. Version ${current} has three switches: student flags, the student sidebar and primary teacher names.`, }, { claim: "What it holds in memory, and for how long.", @@ -227,7 +256,9 @@ export const security = { { date: "2026-10-06", label: "6 October 2026", - version: extensionVersions.next, + /** The code reviewed: the 0.8.4 patch, the rebuild's first steps. Its + fixes are in every later release, and in `next`. */ + version: "0.8.4", findings: "13 to 16", }, ], diff --git a/src/data/site.ts b/src/data/site.ts index 78c5a9a..ff8ec01 100644 --- a/src/data/site.ts +++ b/src/data/site.ts @@ -169,6 +169,14 @@ export const toddleExtension = { supportEmail: "support@nyuchi.com", /** Mailto used while there is no store listing, and for school enquiries. */ enquiry: "mailto:support@nyuchi.com?subject=Toddle%20Enhancement%20Extension", + /** "How to use the Toddle Enhancement Extension" in Nyuchi's help centre: + the page the extension's own Help button opens. */ + help: "https://support.nyuchi.com/en/collections/19764027-how-to-use-the-toddle-enhancement-extension", + /** The Chrome Web Store's update URL, for force-install policies set + outside the Google Admin console. */ + storeUpdateUrl: "https://clients2.google.com/service/update2/crx", + /** The licence server's host, which a school's network should allow. */ + licenceHost: "licences.nyuchi.dev", } as const; /** diff --git a/src/pages/index.astro b/src/pages/index.astro index aa7ff93..896dbf1 100644 --- a/src/pages/index.astro +++ b/src/pages/index.astro @@ -79,8 +79,8 @@ const description =

A Chrome extension for the Toddle gradebook. It expands every rubric - into per-criterion columns, exports the lot to CSV, and hides student - flags with one switch so you can share your screen safely. + into per-criterion columns, exports the lot to CSV, and conceals student + flags with one free switch when you share your screen.

diff --git a/src/pages/legal/cookies.astro b/src/pages/legal/cookies.astro index 312cd45..f642e74 100644 --- a/src/pages/legal/cookies.astro +++ b/src/pages/legal/cookies.astro @@ -11,7 +11,7 @@ * document for their own products; they set them, and they can change them. */ import BaseLayout from "../../layouts/BaseLayout.astro"; -import { legal, updatedLabel } from "../../data/legal"; +import { extensionVersions, legal, updatedLabel } from "../../data/legal"; import { CONSENT_KEY } from "../../data/consent"; import { analytics, toddleExtension } from "../../data/site"; @@ -199,8 +199,10 @@ const rows = [ email address of the Toddle account last seen signed in, so it can check who a licence is for. On Toddle's own site it keeps four small values in the browser's storage: tee-settings, a copy of the switches and of which features the - licence allows (not the key, and no email); gbx-hide-flags, whether - flags are hidden; tee-course-view, whether you chose My classes in the + licence allows (not the key, and no email); tee-blur-flags (gbx-hide-flags in version {extensionVersions.current}), whether flags are concealed; + tee-course-view, whether you chose My classes in the home page filter; and tee-academic-year, the number of the academic year Toddle is showing. None of it is about a student, and the extension sends none of it anywhere. diff --git a/src/pages/legal/data.astro b/src/pages/legal/data.astro index 9a3bd6c..d9adc27 100644 --- a/src/pages/legal/data.astro +++ b/src/pages/legal/data.astro @@ -12,6 +12,7 @@ import BaseLayout from "../../layouts/BaseLayout.astro"; import { dataProtection, extensionVersions, + flags, legal, refunds, updatedLabel, @@ -29,7 +30,7 @@ const held = [ what: "Licence purchases", where: "Nyuchi's licence server and its database, on Cloudflare", fields: - "The email address the key was issued to, and the address that paid if different; the plan; how many were bought; for an organisation licence, the seat count and the buyer's answer to the order question (the school and roughly how many teachers); Buy Me a Coffee's purchase and item references; the key itself; when it was issued, emailed and refunded, its expiry, and its status.", + "The email address the key was issued to, and the address that paid if different; the plan; how many were bought; for an organisation licence, the school's email domains, the seat count and the buyer's answer to the order question (the school and roughly how many teachers); Buy Me a Coffee's purchase and item references; a fingerprint (SHA-256 hash) of the key, never the key itself; when it was issued, emailed and refunded, its expiry, and its status.", }, { what: "The order and payment", @@ -136,13 +137,12 @@ const subprocessors = [ their display titles and emails.
  • - Student flags. From version {extensionVersions.next}, - flags are shown as Toddle shows them, and a staff member can hide them everywhere - with the free flag switch; versions before {extensionVersions.next} hid them by - default. Unless flags are hidden, the sidebar - asks Toddle for a student's active flags each time it opens; while they are - hidden, only when someone presses its eye button. It keeps them only while that - student's sidebar is open. + Student flags. From version {extensionVersions.next}, the extension no longer hides Toddle's own flags, and a staff member can choose + to conceal them for a shared screen with the free flag switch. The sidebar asks Toddle for a + student's active flags (title, description, type and date) each time it opens, + and keeps them only while that student's sidebar is open. {flags.before} In that + version, while flags are hidden, the sidebar asks for them only when someone + presses its eye button.
  • From Toddle's own requests: the sign-in @@ -182,8 +182,8 @@ const subprocessors = [
  • the teacher's switches: the extension on or off, student flags, the student sidebar, My classes, primary teacher names, gradebook tools, and student details on - the Attendance dashboard (versions before {extensionVersions.next} have three: - student flags, the student sidebar and primary teacher names); + the Attendance dashboard (version {extensionVersions.current} has three: student + flags, the student sidebar and primary teacher names);
  • the licence key, if one was entered;
  • @@ -199,7 +199,7 @@ const subprocessors = [

    And four small values in the browser's storage for Toddle's own site: tee-settings, a copy of the switches and of which features the licence allows (no key and no - email); gbx-hide-flags, whether flags are hidden; tee-course-view, + email); tee-blur-flags (gbx-hide-flags in version {extensionVersions.current}), whether flags are concealed; tee-course-view, whether the teacher chose My classes in the home page filter; and tee-academic-year, the number of the academic year Toddle last asked for. No student data is stored. @@ -257,6 +257,20 @@ const subprocessors = [ browser only, and sends it nowhere.

    +

    + The full data schema +

    +

    + This page is the summary. The extension's data schema is the detail: every query it + can send to Toddle, with every field it asks for and what each is used for; every + value it stores, with its shape and when it is deleted; and every request that leaves + the device. It is written for a school's data protection lead or IT team, and for + Toddle. It is checked against the code on every change, so a query the code allows + that the schema does not describe fails the build, and where something could not be + confirmed from the code it is listed as an open question rather than guessed. Ask + {legal.privacyEmail} for a copy. +

    +

    What Nyuchi holds

    None of this comes from Toddle, and none of it is about students. diff --git a/src/pages/legal/privacy.astro b/src/pages/legal/privacy.astro index 98ad55e..aefd5c5 100644 --- a/src/pages/legal/privacy.astro +++ b/src/pages/legal/privacy.astro @@ -168,7 +168,9 @@ const description = meant to, or sends a query that is not on its fixed, read-only list. It has had two adversarial reviews. Every finding of the first, on {security.reviews[0].label}, was fixed in version {security.reviews[0].version}; every finding of the second, on {security.reviews[1].label}, - was fixed in version {security.reviews[1].version} before it is published. + of the code for version {security.reviews[1].version}, a test release, was fixed in + that release, and the fixes are in version {security.next}, the next on the Chrome + Web Store. The Security page sets out the security model, how it is tested, what the reviews found, the limits no extension can remove, and how to report a vulnerability.

    diff --git a/src/pages/legal/security.astro b/src/pages/legal/security.astro index 7336728..2150214 100644 --- a/src/pages/legal/security.astro +++ b/src/pages/legal/security.astro @@ -16,6 +16,7 @@ import BaseLayout from "../../layouts/BaseLayout.astro"; import { extensionVersions, + flags, legal, security, securityMailto, @@ -190,8 +191,10 @@ const severityClass: Record = { Last updated {updatedLabel}. Describes the {toddleExtension.name}: version {security.version}, the one on the Chrome Web Store ({extensionVersions.sameCodeAs} carries the same code), - and version {security.next}, reviewed and not yet published. - Where the two differ, this page says so. For schools, and for the privacy, legal and + and version {security.next}, the next release on the store, reviewed and not yet + published. Between store releases, fixes are tested as patch releases (the newest is + {extensionVersions.latestPatch}), which do not go to the store. Where {security.version} + and {security.next} differ, this page says so. For schools, and for the privacy, legal and IT colleagues who review software on their behalf.

    @@ -341,26 +344,42 @@ const severityClass: Record = { entered, the result of the last check for cancelled keys, and the email of the Toddle account last seen signed in, to check who a licence is for. In Toddle's own site storage, four housekeeping values: a copy of the switches and of which features - the licence allows, whether flags are hidden, the My classes choice, and the academic - year Toddle is showing. No student data is stored anywhere. What it reads about + the licence allows, whether flags are concealed, the My classes choice, and the + academic year Toddle is showing. No student data is stored anywhere. What it reads about students, classes and timetables is held in the Toddle tab's memory until the tab is closed or reloaded; a student's or a class's details are reused for at most 5 minutes, and a student's day for at most 2, before Toddle is asked again.

    - From version {security.next}, student flags are shown as Toddle shows them, and a - staff member can hide them everywhere with the free flag switch; versions - before {security.next} hid them by default. Unless flags are hidden, the sidebar asks Toddle - for a student's flags each time it opens, and keeps them only while it is open. The - CSV export is made in the browser and saved where the teacher's downloads go, by the - teacher's choice. + From version {security.next}, the extension no longer hides Toddle's own student flags; a + staff member can choose to conceal them for a shared screen with the free flag + switch. The sidebar asks Toddle for a student's flags each time it opens, and keeps + them only while it is open. {flags.before} The CSV export is made in the browser and + saved where the teacher's downloads go, by the teacher's choice. +

    + +

    + Out of Toddle's page, into closed shadow roots +

    +

    + The extension is being rebuilt so that as little of it as possible runs where + Toddle's own scripts run. From version {security.next}, the flag switch, the student + sidebar with a class's teachers, and the home page's My classes option and teacher + names run in the extension's own isolated part of the browser. What they draw on + Toddle's pages sits inside closed shadow roots, which no script on Toddle's page can + read or click into, and whether each one runs is decided by the extension's own + switches and licence, never by Toddle's page. What only Toddle's page holds (who was + clicked, the course list as it loads, Toddle's chat and icons) is read by small parts + with no interface of their own, which talk to the extension on private channels set + up before Toddle's own scripts run. The gradebook and the Attendance dashboard are + moving the same way.

    Protections inside the page

    - Part of the extension has to run inside Toddle's page to read the gradebook, which - means it shares that page with Toddle's own scripts. It is protected as far as a page - allows: + Part of the extension still has to run inside Toddle's page, to read the gradebook and + what Toddle draws, which means it shares that page with Toddle's own scripts. It is + protected as far as a page allows:

      = {

      {secondReview.label}

      - The second review covered everything new in version {secondReview.version}: the - extension's own pages, rebuilt; the first rebuilt part that runs on Toddle's pages - (the flags switch, in a closed shadow root that no script on the page can reach); the - build that makes them; and the new switches. It also re-read the code that runs in - Toddle's page against the claims made about it. It found two medium-severity issues - and two low (findings {secondReview.findings}). All were fixed in - version {secondReview.version} before it is published, and none was in - version {security.version}. + The second review covered everything new in version {secondReview.version}, a test + release: the extension's own pages, rebuilt; the first rebuilt part that runs on + Toddle's pages (the flags switch, in a closed shadow root that no script on the page + can reach); the build that makes them; and the new switches. It also re-read the code + that runs in Toddle's page against the claims made about it. It found two + medium-severity issues and two low (findings {secondReview.findings}). All were fixed + in version {secondReview.version}, and the fixes are in every release after it, + including {security.next}. None was in version {security.version}. Each later + step of the rebuild (the student sidebar, the home page) was reviewed the same way as + it was made, and what those reviews found about the page's limits is set out below.

      { @@ -540,9 +561,9 @@ const severityClass: Record = { that wants that risk reduced further should raise it with Toddle.

      - The flag switch is a privacy aid, not a security control. It hides flags from the + The flag switch is a privacy aid, not a security control. It conceals flags on the screen; it does not hide names, and does not stop anyone deliberately opening a - student's profile. + student's flags or profile. {flags.limit}

      @@ -560,9 +581,9 @@ const severityClass: Record = {
    • can read the per-load secrets, which stop only scripts that are not listening, and replay them in that browser: switch a licensed feature on, give the licence check - another account's email, or show flags that were hidden. It gains no student data by - it, because it already runs with the teacher's session and could read Toddle - directly; + another account's email, or clear flags that were concealed. It gains no student + data by it, because it already runs with the teacher's session and could read + Toddle directly;
    • cannot overhear the answers to the extension's queries, but can answer first with @@ -571,7 +592,13 @@ const severityClass: Record = {
    • is stopped from pressing the extension's message buttons, but can tell Toddle's own - app to open a chat in any case. + app to open a chat in any case; +
    • +
    • + if it was in the page before Toddle's own scripts (a page that opened Toddle in a + new window can be), can take the private channel the home page's part uses, and so + show a wrong teacher's name, as text, or offer My classes where it should not. + Whether a feature runs is still never decided from the page.

    diff --git a/src/pages/legal/student-privacy.astro b/src/pages/legal/student-privacy.astro index c12d853..b3dce6b 100644 --- a/src/pages/legal/student-privacy.astro +++ b/src/pages/legal/student-privacy.astro @@ -7,7 +7,13 @@ * enforced by the extension's closed-loop tests. */ import BaseLayout from "../../layouts/BaseLayout.astro"; -import { dataProtection, legal, updatedLabel } from "../../data/legal"; +import { + dataProtection, + extensionVersions, + flags, + legal, + updatedLabel, +} from "../../data/legal"; import { toddleExtension } from "../../data/site"; const title = "Student privacy — Nyuchi Learning"; @@ -70,6 +76,21 @@ const privacyMail = `mailto:${legal.privacyEmail}`; who can see what is still decided by the school's Toddle permissions.

    +

    Student flags

    +

    + Toddle lets a school mark students with flags, and those flags are the most sensitive + thing a teacher's screen can show. From version {extensionVersions.next}, the + extension no longer hides Toddle's own flags, so staff see what the school has recorded. + What it adds is flag visibility for a shared screen: a teacher can conceal flags + with one free switch before the screen is shown to a class, a parent or a visitor, + so what a flag says cannot be read from across the room. {flags.reveal} +

    +

    + The sidebar reads a student's active flags from Toddle each time it opens, shows them + in that teacher's browser only, and forgets them when it closes. They are never + stored and never sent anywhere. {flags.limit} +

    +

    FERPA

    Because no student data is collected, stored or transmitted by Nyuchi, Nyuchi does not diff --git a/src/pages/legal/terms.astro b/src/pages/legal/terms.astro index 3a6aa82..feba7dc 100644 --- a/src/pages/legal/terms.astro +++ b/src/pages/legal/terms.astro @@ -58,8 +58,8 @@ const description =

    What it costs

    - Hiding student flags is free and is not licensed. It protects a child, so it is not - something we will ever put behind a payment. The My classes filter on the Toddle + Concealing student flags for a shared screen is free and is not licensed. It + protects a child, so it is not something we will ever put behind a payment. The My classes filter on the Toddle home page is free too. A licence covers the gradebook's per-criterion columns, the CSV export, the student sidebar, primary teacher names and the Attendance dashboard's student details. @@ -156,7 +156,7 @@ const description = works by reading the interface Toddle's own web app uses. Toddle does not publish that interface and is under no obligation to keep it stable. A Toddle release can change it, and when that happens a column may stop appearing or a flag may stop being - hidden. + concealed.

    We will fix breakages as quickly as we can, and the extension is built to fail diff --git a/src/pages/toddle-enhancement-extension.astro b/src/pages/toddle-enhancement-extension.astro index bdc30fe..9818b5c 100644 --- a/src/pages/toddle-enhancement-extension.astro +++ b/src/pages/toddle-enhancement-extension.astro @@ -7,12 +7,17 @@ * know what it can see before putting it on a hundred machines. The flag * switch gets the most room because it is the part people will be asked to * justify. + * + * It describes version 0.9.0 (`extensionVersions.next`), the next release on + * the Chrome Web Store, and says where 0.8.2, on the store today, differs. + * Flags are "concealed", never "hidden": the extension no longer hides + * Toddle's own flags (see `flags` in src/data/legal.ts). */ import { Picture } from "astro:assets"; import type { ImageOutputFormat } from "astro"; import BaseLayout from "../layouts/BaseLayout.astro"; import { toddleExtension } from "../data/site"; -import { extensionVersions, pricing, refunds, toddleNotice } from "../data/legal"; +import { extensionVersions, flags, pricing, refunds, toddleNotice } from "../data/legal"; import gradebookShot from "../assets/screenshots/01-gradebook.jpg"; import sidebarShot from "../assets/screenshots/02-student-sidebar.jpg"; import todayShot from "../assets/screenshots/03-today.jpg"; @@ -38,9 +43,10 @@ const primaryCta = live ? { label: "Add to Chrome", href: toddleExtension.webStore! } : { label: "Tell me when it is live", href: toddleExtension.enquiry }; -/* `free` is the split the extension enforces: the flag switch and My classes - for everyone, the rest with a licence. Keep it in step with `pricing` in - src/data/legal.ts and the terms. */ +/* `free` is the split the extension enforces (its docs/licensing.md and + app/features/registry.ts): the flag switch and My classes for everyone, the + rest with a licence. Keep it in step with `pricing` in src/data/legal.ts, + the terms, and the licence email (nyuchi-licence-server, src/email.js). */ const features = [ { mineral: "cobalt", @@ -51,8 +57,8 @@ const features = [ { mineral: "malachite", free: true, - title: "Hide student flags", - body: `One switch in the Toddle header hides flags across Toddle: the gradebook, Attendance, the class portfolio, submissions, search results, profile headers and the student sidebar. An eye button shows one student's flags when you need them. It stays as you left it, so you can arm it before a lesson. From version ${extensionVersions.next}, flags show as Toddle shows them until you switch them off; earlier versions hid them from the start.`, + title: "Conceal student flags", + body: `${flags.summary} The switch sits in Toddle's header and the extension's menu, and stays as you left it, so you can set it before a lesson.`, }, { mineral: "gold", @@ -64,25 +70,25 @@ const features = [ mineral: "tanzanite", free: true, title: "My classes", - body: "The Toddle home page's course filter gains a third option beside All courses and My courses: only the classes you actually teach. It is remembered, and a tag by the heading says when it is on.", + body: "The Toddle home page's course filter gains a third option beside All courses and My courses: only the classes you actually teach. It switches on and off at once, it is remembered, and a tag by the heading says when it is on. It only appears where you are on a class.", }, { mineral: "terracotta", free: false, title: "The student sidebar", - body: "Click a student anywhere they appear in Toddle — class pages, name links, gradebook student cells, every tab of the Attendance dashboard — and they dock to the side until you close it: one larger photo, grade · age · class of, Student Group, room number, homeroom advisor, and contacts with their relationship, tap-to-call phone and email.", + body: "Click a student anywhere they appear in Toddle — class pages, name links, gradebook student cells, every tab of the Attendance dashboard — and they dock to the side until you close it: one larger photo, grade · age · class of, their email (click to copy it, or the envelope to write), Student Group, room number, homeroom advisor, and contacts with their relationship, tap-to-call phone and email. In School setup, Toddle's admin portal, it steps aside, so a click there does what Toddle does.", }, { mineral: "copper", free: false, - title: "Now, and today", - body: "Beside the photo, a Now card: the student's attendance code for the block happening now, the block, class, room and timetabled teacher — or their next class, or that they are finished or have no classes. Below, today's daily attendance code, and their classes in two tabs: Today, in time order with each period's attendance code and the current one first, and All.", + title: "Now, and today's timetable", + body: "Beside the photo, a Now card: the student's attendance code for the block happening now, the block, class, room and timetabled teacher. Today's timetable is its own part: today's periods in time order with each one's attendance code, “No classes today”, or “Couldn't load timetable” with a Retry button. The rest of the panel never waits for it.", }, { mineral: "sodalite", free: false, title: "The class view, and messages", - body: "Click a class for the block it is in now, its primary teacher, parent course and room, and every teacher with their display title and email. Message buttons for staff, the student, the family channel and each family member open Toddle's own chat, under your school's messaging rules.", + body: "Click a class for the block it is in now, its primary teacher, parent course and room, and every teacher with their display title and email. Tick the teachers you want and email them all at once, or copy their addresses. Message buttons for staff, the student, the family and each family member open Toddle's own chat, under your school's messaging rules.", }, { mineral: "cobalt", @@ -135,13 +141,17 @@ const shots = [ caption: "My classes · Free", }, { + /* Taken in version 0.8.2, which hid flags; retake it on 0.9.0. The alt + text describes the picture as it is. */ src: flagsShot, - alt: "A student's profile card in Toddle with a Show flags button where the flags would be, so they stay hidden until pressed; personal details are hidden behind grey bars.", - caption: "Hide student flags · Free", + alt: "A student's profile card in Toddle with a Show flags button where the flags would be, as in version 0.8.2; personal details are covered by grey bars.", + caption: "The flag switch · Free", }, { + /* Taken in version 0.8.2; 0.9.0 has a switch for every feature, grouped + by where it works. Retake it on 0.9.0. */ src: menuShot, - alt: "The extension's toolbar menu: the organisation licence and version, a Show student flags switch under Free, Student sidebar and Primary teacher names switches under With a licence, and Send feedback and Help.", + alt: "The extension's toolbar menu in version 0.8.2: the organisation licence and version, a Show student flags switch under Free, Student sidebar and Primary teacher names switches under With a licence, and Send feedback and Help.", caption: "The toolbar menu", }, { @@ -159,12 +169,13 @@ const shots = [ const facts = [ { label: "Where it runs", - value: "Only on web.toddleapp.com. It has no access to any other site.", + value: + "Only on web.toddleapp.com. It has no access to any other site. From version 0.9.0 the flag switch, the student sidebar and the home page's additions run in the extension's own isolated part of the browser, drawn inside closed shadow roots that no script on Toddle's page can read or click into; the gradebook and the Attendance dashboard are moving the same way.", }, { label: "What it reads", value: - "What Toddle already lets you see — gradebook results, rubric descriptors and levels as your school set them up, class staff, student details, today's timetable and attendance, and a student's flags when they are shown — through an exact list of read-only queries to Toddle's own API, for you at the screen, reusing the session you are already signed in with. It never asks for your password. Toddle's sign-in headers stay in the tab's memory, in one script in Toddle's page, and go nowhere but Toddle.", + "What Toddle already lets you see — gradebook results, rubric descriptors and levels as your school set them up, class staff, student details, today's timetable and attendance, and a student's flags each time the sidebar opens — through an exact list of read-only queries to Toddle's own API, for you at the screen, reusing the session you are already signed in with. It never asks for your password. Toddle's sign-in headers stay in the tab's memory, in one script in Toddle's page, and go nowhere but Toddle.", }, { label: "What it writes", @@ -184,13 +195,13 @@ const facts = [ { label: "What it stores", value: - "On your own machine only: your switch settings, your licence key if you have one, the result of the last check for cancelled keys, and the email of the Toddle account last seen signed in, to check who a licence is for; and, in Toddle's own site storage, a copy of the switches, whether flags are hidden, your My classes choice and the academic year Toddle is showing. No student data: what it reads is held in the tab's memory until the tab is closed or reloaded, and never written to storage.", + "On your own machine only: your switch settings, your licence key if you have one, the result of the last check for cancelled keys, and the email of the Toddle account last seen signed in, to check who a licence is for; and, in Toddle's own site storage, a copy of the switches, whether flags are concealed, your My classes choice and the academic year Toddle is showing. No student data: what it reads is held in the tab's memory until the tab is closed or reloaded, and never written to storage.", }, ]; const title = "Toddle Enhancement Extension — Nyuchi Learning"; const description = - "A Chrome extension for the Toddle gradebook: every rubric expanded into per-criterion columns, CSV export, and a switch that hides student flags so you can share your screen without compromising privacy."; + "A Chrome extension for the Toddle gradebook: every rubric expanded into per-criterion columns, CSV export, a student sidebar, and a free switch that conceals student flags when your screen is shared."; /* The claims here are the ones a search result or an assistant will repeat, so they mirror the privacy policy rather than the marketing copy. */ @@ -213,10 +224,10 @@ const schema = [ publisher: { "@id": "https://learning.nyuchi.com/#organization" }, featureList: [ "Expands every Toddle assessment tool into per-criterion columns", - "Hides student flags across Toddle with one switch", + "Conceals student flags across Toddle with one free switch, for a shared screen; never hides Toddle's own flags", "CSV export of results and submission status", "A My classes filter on the Toddle home page", - "A student sidebar anywhere a student appears in Toddle: photo, grade, contacts, where they are now, today's classes and attendance", + "A student sidebar anywhere a student appears in Toddle: photo, grade, email, contacts, where they are now, today's timetable and attendance", "A class view with every teacher, and message buttons that open Toddle's own chat", "The Attendance dashboard's Students tab with each student's year group, current class and teacher", "Primary teacher names beside each class", @@ -345,26 +356,26 @@ const schema = [

    Toddle marks students with flags. They are useful — that is the point of - them — and they are exactly what you do not want on a projector, in a + them — and what they say is exactly what you do not want on a projector, in a screen share with a parent, in a lesson observation, or in a screenshot - pasted into a planning document. One switch takes them off the screen. + pasted into a planning document. One switch conceals them while your screen + is shared.

  • -

    It hides flags, not names

    +

    It conceals flags, not names

    Students stay identifiable to you — you are still teaching, and a - gradebook of anonymous rows is no use to anyone. It is the flag that - comes off the screen, because that is the piece of information the + gradebook of anonymous rows is no use to anyone. It is what a flag says + that comes off the screen, because that is the piece of information the room should not be reading over your shoulder.

    - Toddle draws the gradebook on an HTML canvas, so a flag there cannot - be hidden with styling. The extension empties the flag out of the - cell before the browser paints it, and hides the ones Toddle - renders as ordinary page elements everywhere else. + The extension no longer hides Toddle's own flags: they stay where Toddle puts + them, with their links and documents in Toddle's student popover. Concealing + them is your choice, off until you switch it on. {flags.reveal}

    @@ -373,14 +384,14 @@ const schema = [

    It stays on. The setting persists as you move around Toddle and across browser sessions, so it - is something you arm before a lesson rather than something you have + is something you set before a lesson rather than something you have to remember at the worst possible moment.

    The switch shows its state. - It sits in the Toddle header and reads as on or off at a glance — - check it before you share, the same way you check the right window is - selected. + It sits in the Toddle header, the same size as Toddle's own buttons, and + reads as on or off at a glance — check it before you share, the same way + you check the right window is selected.

    @@ -389,12 +400,15 @@ const schema = [

    What it does not do

    - It hides flags. It does not hide names, and it does not stop anyone - opening a student's profile deliberately. It works by changing what - Toddle draws, which means it depends on Toddle's own markup and a - Toddle release could change that. Arm it before you share, check the - switch is on, and treat it as a good lid — not as a compliance control - and not as a substitute for your school's safeguarding practice. + It conceals flags. It does not hide names. {flags.limit} It works by + changing what Toddle draws, which means it depends on Toddle's own markup, + and a Toddle release could change that. Switch it on before you share, check + it is on, and treat it as a good screen — not as a compliance control and not + as a substitute for your school's safeguarding practice. +

    +

    + This describes version {extensionVersions.next}, the next release on the + Chrome Web Store. {flags.before}

    @@ -425,15 +439,23 @@ const schema = [ Press Add to Chrome. Chrome asks you to confirm, and that is the install. -
  • Open any Toddle gradebook: Gradebook → Assessments.
  • - The new columns appear, and the flag switch is in the Toddle header, ready - before your next lesson. + A welcome page opens once: what it does, a switch for every feature, and a box + for a licence key if you have one. +
  • +
  • + Open Toddle. The flag switch is in Toddle's header, and My classes is in the + home page's course filter. With a licence, the per-criterion columns are in any + gradebook (Gradebook → Assessments) and a click on a student opens the + sidebar.
  • No files to download, no Developer mode, nothing to unzip. Updates arrive on - their own, the way every other Chrome extension does. + their own, the way every other Chrome extension does. Stuck? + How to use the extension, in our help centre.

    {primaryCta.label} @@ -442,16 +464,50 @@ const schema = [

    For a school

    Push it from the Admin console

    - Because it is on the Chrome Web Store, IT can force-install it to a teaching - organisational unit by its extension ID — the standard route, with no - self-hosted package to maintain and no Developer mode on anyone's machine. - Nothing for staff to click, and updates arrive on their own. + Because it is on the Chrome Web Store, IT can install it for every teacher by its + extension ID, with no self-hosted package to maintain and no Developer mode on + anyone's machine. Chrome keeps it up to date from the store. +

    +
      +
    1. + In the Google Admin console, go to Devices → Chrome → Apps & extensions → Users & browsers, and pick the organisational unit your teachers are in. Students have no use + for it. +
    2. +
    3. + Add it by ID: {toddleExtension.extensionId}, from the Chrome Web Store. +
    4. +
    5. + Choose Force install for a rollout IT + owns, or Allow install to leave it to + each teacher. Pinning it to the toolbar puts its menu one click away. +
    6. +
    +

    + Without the Admin console, the same force-install policy works through Group + Policy or Intune on Windows and a configuration profile on macOS, with the ID and + the store's update URL, + {toddleExtension.extensionId};{toddleExtension.storeUpdateUrl}. +

    +

    + The licence. An organisation licence is + one key for your school's email domain. A key cannot be pushed by policy, so send + it to staff; each teacher pastes it in once, from the welcome page or the + toolbar menu's Enter a licence key. If your network filters outbound + traffic, allow {toddleExtension.licenceHost} + so the daily check for cancelled keys can run. If it is blocked, licences keep + working on the last result.

    - The extension ID is - {toddleExtension.extensionId}. We will send - you the console steps and the full answer to "what can this thing see?" — which - somebody will ask, and should. + We will send you the full deployment guide, and the full answer to "what can this + thing see?" — which somebody will ask, and should.

    Talk to us about a rollout @@ -465,7 +521,7 @@ const schema = [

    Pricing

    - Hiding flags is free. Always. + Concealing flags is free. Always.

    The flag switch protects a student, so it is not behind a price and never will @@ -555,6 +611,14 @@ const schema = [ }

    + The data schema. Every piece of Toddle + data the extension reads, every value it stores and every request it makes is + listed, field by field, in its data schema, written for a school's data + protection lead or IT team. It is checked against the code on every change: a + query the code allows that the schema does not describe fails the build. Ask us + for a copy. +

    +

    If your IT team would rather verify this than take our word for it, a Chrome extension is a folder of readable JavaScript — they can unpack the installed package and read every line of it. We will also answer @@ -588,7 +652,16 @@ const schema = [ gradebook, and tells you when something could not be expanded rather than quietly showing you less. Report a break and we will chase the rename.

    +

    + How updates reach you. Fixes are made and + tested as small patch releases, which do not go to the Chrome Web Store. When a + batch of them is ready, it is published to the store as the next version ({extensionVersions.next} is + next), and Chrome installs it on its own. +

    + How to use it Report a problem {toddleExtension.supportEmail} diff --git a/tests/links.test.ts b/tests/links.test.ts index cf1bc2c..e1164e1 100644 --- a/tests/links.test.ts +++ b/tests/links.test.ts @@ -96,11 +96,21 @@ describe("the extension page", () => { expect(extensionPage).toContain("What it does not do"); }); - /* The shipping feature hides flags and deliberately never hides names. + /* The feature conceals flags and deliberately never hides names. Describing it as anonymising the class would be a false claim on a page a school reads before trusting it. */ it("does not claim to hide student names", () => { - expect(extensionPage).toContain("It hides flags, not names"); + expect(extensionPage).toContain("It conceals flags, not names"); expect(extensionPage).not.toMatch(/Present mode/); }); + + /* From 0.9.0 the extension never hides Toddle's own flags: a teacher + conceals them for a shared screen. "Hide flags" would promise the old + behaviour. Only the line about 0.8.2 (`flags.before` in legal.ts) may + say what that version did. */ + it("says flags are concealed, not hidden", () => { + for (const source of [extensionPage, home]) { + expect(source).not.toMatch(/\bhid(e|es|ing) (student |toddle's )?flags/i); + } + }); }); diff --git a/tests/seo.test.ts b/tests/seo.test.ts index 1d0259d..cd31d57 100644 --- a/tests/seo.test.ts +++ b/tests/seo.test.ts @@ -121,7 +121,8 @@ describe("crawlers and assistants", () => { const llms = built("llms.txt"); expect(llms.startsWith("# Nyuchi Learning")).toBe(true); // The two claims most likely to be repeated back by an assistant. - expect(llms).toContain("It hides flags, not names"); + expect(llms).toContain("It conceals flags, not names"); + expect(llms).not.toMatch(/\bhid(e|ing) (student |toddle's )?flags/i); expect(llms).toContain("transmits nothing"); }); });