diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 21046fd..be2533a 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -18,6 +18,8 @@ jobs:
cache: npm
- run: npm ci --ignore-scripts --no-audit --no-fund
- run: npm run typecheck
+ - name: Validate AI literacy lesson and reviewed data
+ run: node scripts/validate-ai-literacy.cjs
- name: Verify tests or expected starter state
shell: bash
run: |
diff --git a/README.md b/README.md
index 896604e..0241536 100644
--- a/README.md
+++ b/README.md
@@ -31,6 +31,7 @@ The [guide homepage](./docs/index.html) is the canonical orientation page. It as
| [Accessibility](./docs/accessibility/index.md) | Describe functional barriers without disclosing unnecessary medical information. |
| [Technology planning](./docs/technology-planning/index.md) | Translate tasks and barriers into minimum, preferred, and alternative configurations. |
| [Funding research](./docs/funding/README.md) | Research programs by jurisdiction and verify current rules. |
+| [AI literacy and rubric writing](./docs/ai-literacy/index.html) | Learn to question and evaluate fictional AI responses; no coding or account required. |
| [MCP prompt library](./docs/prompts/README.md) | Use AI research while preserving human judgment and source verification. |
| [Preparation templates](./docs/templates/README.md) | Prepare a needs statement, quotes, questions, and an approval packet. |
| [Worked example](./docs/case-study/README.md) | Follow an anonymized retraining plan from goal through lessons learned. |
diff --git a/docs/ai-literacy/SOURCE_RECORD.md b/docs/ai-literacy/SOURCE_RECORD.md
new file mode 100644
index 0000000..8ac6e56
--- /dev/null
+++ b/docs/ai-literacy/SOURCE_RECORD.md
@@ -0,0 +1,63 @@
+# AI literacy source and implementation record
+
+Reviewed 7 November 2026. This is a proposed educational addition, pending maintainer review and publication.
+
+## Continuity
+
+Base: `Loptr-Lab/training` main `877c4bfe4ce6ca677667be735df747a6e7e63369`.
+Inspected all remote branches, current open issues (#42, #45), open PRs (#38, #47, #50, #52), existing prompt library, reviewer scorecard, CONTRIBUTING, contributor governance, PIXIE contributor instructions, shared stylesheet and reading controls. No existing introductory rubric class was located. Preserve those assignments and the existing site; no other project repository, PIXIE backend/authentication/release or plugin is changed.
+
+Read the [canonical ecosystem architecture](https://github.com/ibloud/ibloud.github.io/blob/main/docs/ECOSYSTEM_ARCHITECTURE.md). PIXIE list_projects and refreshed training status were consulted; its dated snapshot predates current main and was not treated as current capability verification. prepare_checkpoint produced an unsubmitted draft for this task. No issue, membership or assignment is claimed. If using that workflow, the participant reviews public visibility and GitHub attribution before submitting and retains that issue URL. Continue progress there; do not add a second tracker.
+
+## Source checks
+
+Direct shell HTTPS to the research domains was blocked by the environment allowlist. The connected web research tool retrieved the following original-publisher pages on 7 November 2026. Accessing a reference does not imply endorsement. No external article was copied into the course.
+
+| Reference | Evidence and use |
+| --- | --- |
+| [BLS, 16 July 2026](https://www.bls.gov/opub/ted/2026/artificial-intelligence-information-technology-and-employment-2024-34.htm) | Original table: data scientists 33.5%; software developers 15.8%; total employment 3.1%, all projected 2024–34. Also discusses occupations with declining demand. |
+| [BLS, January 2026 overview](https://www.bls.gov/opub/mlr/2026/article/industry-and-occupational-employment-projections-overview.htm) | Chart 3 and occupational table: computer and mathematical group 10.1%, 2024–34. Population includes wage/salary jobs and self-employment. |
+| [Stanford HAI AI Index 2026](https://hai.stanford.edu/ai-index/2026-ai-index-report) | Report landing page and capability/economic overview retrieved. Used for uneven capabilities and further reading; no benchmark statistics republished. |
+| [Stanford Report, 21 October 2026](https://news.stanford.edu/stories/2026/10/ai-labor-market-economic-trends-data) | Describes payroll-based early-career declines, data representation cautions and dashboards. Summarized without conflating observed trends with projections or causal proof. |
+| [Lightcast 2026](https://lightcast.io/resources/research/stanford-ai-index-2026) | Publisher page retrieved; describes job-posting/skills data. Linked as context; no numerical claims imported. |
+| [OpenAI evaluation best practices](https://developers.openai.com/api/docs/guides/evaluation-best-practices) | Concepts and evaluation guidance retrieved. Intermediate reference; no hosted evaluation dependency. |
+| [Microsoft eval-guide](https://github.com/microsoft/eval-guide) | Repository overview retrieved. Intermediate agent evaluation guidance. |
+| [Anthropic educational evals](https://github.com/anthropics/k12-teacher-skills/tree/main/evals) | Web tool could not retrieve this subdirectory. GitHub API directory listing and raw `evals/README.md` retrieved successfully; contains classroom-artifact rubrics and human/deterministic evaluation use. Beginner to intermediate reading. |
+| [Inspect scoring](https://inspect.aisi.org.uk/scoring.html) | Documentation retrieved. Advanced software framework with standard/custom scoring. |
+| [Google ADK criteria](https://github.com/google/adk-docs/blob/main/docs/evaluate/criteria.md) | File retrieved. Advanced agent evaluation metrics. |
+| [NIST AI RMF](https://www.nist.gov/itl/ai-risk-management-framework) | Official framework landing page retrieved; risk-management context for checking unsupported claims. |
+| [BLS Occupational Outlook Handbook](https://www.bls.gov/ooh/) | Retrieved; independent non-referral career research route. |
+| [Handshake referral](https://joinhandshake.com/move-program/referral?referralCode=AB04EB&utm_source=referral) | Owner-supplied URL retained verbatim with visible financial-interest disclosure and `rel=sponsored`. Exact referral destination and this code’s/account’s eligibility remain **unverified**: web tool could not access it; direct HTTPS remained blocked. Main Handshake website and official Help Center terms were retrieved, which do not verify this specific referral route or account. Reward numbers, caps, UK role examples and vacancy claims are omitted from learner copy. |
+
+The user approved read-only HTTPS access to seven requested source domains during this task. Refreshing environment status still showed the original allowlist; a fresh direct Handshake request remained 403. No proxy or access policy was bypassed. Other references were verified through the connected research tool as above. Check the exact referral destination manually before publication. Official Help Center guidance and terms (updated 13 August 2026) were subsequently retrieved through connected web research: [program guidance](https://support.joinhandshake.com/hc/en-us/articles/32245577478295-Referring-someone-to-the-Handshake-AI-Fellowship), [terms](https://support.joinhandshake.com/hc/en-us/articles/34271833422871-Handshake-AI-Fellowship-Referral-Program-Terms-of-Service). These support the general 10%/10-hour/40-hour description with a six-month window and active-account/onboarding/paid-production qualifications, but do not establish the owner’s account or referral code eligibility. The course links the official terms and retains the general financial-interest disclosure without numerical inducements.
+
+## Data architecture decision
+
+| Approach | Cost and reliability | Decision |
+| --- | --- | --- |
+| Versioned static JSON plus HTML | No service cost, works without JavaScript; reviewed values are reproducible. Manual updates can become old. | Implemented. JSON holds provenance and values; publication validator checks HTML parity and required metadata. Visible verification date always remains. Optional age text warns after 180 days. |
+| Scheduled refresh | Requires a stable machine-readable series, schema/range checks, failure retention and approved publishing workflow. Existing CI validates a starter engine; no approved data-release workflow or verified feed was found. | Deferred. No scheduled job, scraping, credentials or API dependency added. |
+| Outbound maintained research links | No local feed cost; destinations change and depend on internet access. | Included alongside snapshot as further context, not embedded “live” data. |
+
+Updates require a reviewed PR: verify original publication, population, units and period; update JSON, HTML and verification date/age constant together; run publication checks. Missing data must not become estimates. No automatic refresh exists, so refresh-failure testing is inapplicable; browser tests simulate an old snapshot. A missing remote source does not remove the retained HTML/JSON.
+
+## Teaching and privacy limits
+
+All task facts, vendor names, travelers, rates, dates and responses in the itinerary are explicitly fictional. No model API, accounts, analytics, fetch requests or learner database. Reading preferences retain the existing device-local controls. Written criteria live in memory until reset/reload, with an explicit download option. Text is rendered with textContent, not interpreted as HTML.
+
+Multiple-choice practice is deterministically checked with one retry. Open writing gets keyword-based wording hints, a worked correction reference after revision, and a targeted human self-review checklist. These hints are not semantic grading. The eight-check worked rubric is expressly incomplete: B can earn 12 despite violating the dietary requirement; the class explains adding full coverage/hard gates. No score implies qualification or acceptable real-world performance.
+
+## Local preview and review boundary
+
+`python -m http.server 8765 --directory docs`, then open `http://localhost:8765/ai-literacy/`.
+No Vercel configuration, existing project binding or deployment workflow was found. No new Vercel project or production deployment was created. The public GitHub Pages URL reflects approved main, not this feature branch. Maintainer approval controls merging and publication.
+
+## Classroom-pilot additions requested during review preparation
+
+The user requested fresh scenarios, an end scoring record, two unsuccessful attempts with a scenario-specific study guide after the first and an alternative learning route after the second, and Cornell as further study.
+
+Implemented a local seeded fictional-scenario generator. Each page session uses a fresh browser-crypto seed; download preserves the seed, facts and response. A second assessment attempt keeps its study facts and changes the mistakes. Fixed arithmetic generation supports deterministic checking without adding a model service or changing PIXIE. The eight teaching practices retain their own one-retry behavior; the final assessment separately allows two full four-step attempts. Its explicit target is 4/4, chosen for this exercise, not validated as a hiring or qualification standard.
+
+First unsuccessful assessment: guide addresses the particular incorrect total, closure interpretation or signed-score step. Second unsuccessful assessment: alternative tasks refer only to correct checks observed in either attempt; if none were correct, the page offers interest-based tracks without inventing strengths. No conclusion about employment suitability is made. Session evidence, guide and next action can be downloaded and reviewed before manually sharing a synthetic checkpoint with PIXIE. No automatic classroom progress database, cross-session failure count or plugin integration is claimed.
+
+[Cornell Center for Teaching Innovation: Using rubrics](https://teaching.cornell.edu/teaching-resources/assessing-student-learning/using-rubrics) was retrieved and verified via connected web research on 7 November 2026. This is a teaching-resource guide, not an enrolled class. It discusses measurable criteria, feedback and revision; broader performance-level rubrics differ from the atomic PASS/FAIL lesson. Linked in the resource library and scenario study guides. Cornell is not a program partner or endorser.
diff --git a/docs/ai-literacy/VALIDATION.md b/docs/ai-literacy/VALIDATION.md
new file mode 100644
index 0000000..0685cdb
--- /dev/null
+++ b/docs/ai-literacy/VALIDATION.md
@@ -0,0 +1,51 @@
+# AI literacy review evidence
+
+7 November 2026. Feature-branch proposal; no deployment or physical-device acceptance claimed.
+
+## Verified locally
+
+- `node scripts/validate-ai-literacy.cjs`: PASS. Required snapshot provenance, four HTML/data values, local links/fragments, eight steps, exact per-person/party costs, signed scoring and split-weight arithmetic.
+- `node --check docs/ai-literacy/rubrics.js` and `snapshot.js`: PASS.
+- `npm run typecheck`: PASS.
+- `ARTIFACT_DIR=/workspace/work node scripts/test-ai-literacy-browser.cjs`: PASS using installed Playwright and `/usr/bin/chromium` against a local static server. All seven quizzes: incorrect attempt, one retry, correction reveal, reset and correct answer. Score practice: signed penalty, retry, reset. Writer: zero-weight rejection, targeted hints, revision example, three drafts, download, reset. Skip-link keyboard route, 20 theme/viewport/largest-text reflow cases (320, 375, 768, 1024, 1440px), simulated snapshot age over 180 days, no-JavaScript answer access and no browser errors.
+- Automated axe-core WCAG 2 A/AA and 2.1 AA scan: zero violations or incomplete findings across both pages in both dark and light themes, using local Chromium. This is an automated scan, not screen-reader acceptance.
+- Inspected rendered mobile screenshot. Fixed a long native select overflowing at 320px/largest text; all reflow cases then passed. Simplified the labor table to two columns with adjacent source links for narrow screens.
+- `git diff --check`: PASS.
+- `npm ci --cache /workspace/work/npm-cache --ignore-scripts --no-audit --no-fund`: PASS. Initial default cache installation failed because the environment's home cache was unavailable; changing only the cache path succeeded. No package/dependency changes.
+
+## Baseline starter tests
+
+Before changes: both Jest suites fail; 24/24 tests fail on `Not implemented` starter engine methods. After changes: the same two suites and 24 failures remain. No engine, engine tests or starter assignment was modified. Existing CI explicitly permits the documented starter state. Do not describe the entire test suite as passing.
+
+## Reproduce
+
+From repository root:
+
+```sh
+node scripts/validate-ai-literacy.cjs
+npm run typecheck
+npm test -- --runInBand
+python -m http.server 8765 --directory docs
+```
+
+Open `http://localhost:8765/ai-literacy/`. In another terminal, where Playwright and a browser are available:
+
+```sh
+BASE_URL=http://127.0.0.1:8765 BROWSER_EXECUTABLE=/usr/bin/chromium node scripts/test-ai-literacy-browser.cjs
+```
+
+Playwright/axe were available or installed only in the review workspace, not added to the site's package manifest. The publication validator runs in existing CI without new dependencies. There is no application build script: `docs/` is the static site payload; no build step or new hosting service is required.
+
+## Remaining acceptance
+
+- Physical iPad Safari, VoiceOver, actual browser zoom and independent beginner completion have not been tested. Largest reading size and narrow CSS viewport tests do not substitute for those checks. WebKit launch was attempted but its browser executable is not installed in this environment.
+- Exact owner-provided Handshake referral destination/account eligibility remains unverified; official general terms are retrieved and linked. Check the exact URL manually before publishing. Reward numbers and vacancy claims are omitted.
+- Open-ended feedback is a keyword heuristic, never a semantic grader; learners must use the provided checklist and evidence.
+- No Vercel binding/configuration or existing preview workflow was found. Local preview only; no new Vercel project, production deployment, main push or merge.
+- BLS/Stanford evidence and reference verification are recorded in SOURCE_RECORD.md. Static snapshot chosen over an unapproved scheduled publisher. No automatic refresh exists; failure-retention tests for a scheduled job are inapplicable.
+
+## Additional classroom-pilot verification
+
+- 1,024 generated scenario variants (512 seeds × two attempts): PASS. Independently recomputed synthetic prices, meal costs, shuttle allocation, per-person/party totals, printed-response comparisons and signed scoring. Verified study facts remain unchanged on the second attempt while all three response outcomes change; positive, negative and zero scores occur.
+- Browser assessment paths: first-attempt success; first failure with scenario guide and Cornell link; second-attempt success; two failures with observed number-checking, rule-checking or arithmetic routes; two failures with no demonstrated strength and an interest-based route. No third assessment attempt offered. Both attempts appear in the downloaded record. Existing eight-step quiz/retry/reset checks still pass.
+- No correct-answer feedback is revealed during a final assessment attempt; the completed attempt provides evidence and study. Local record is learner-produced, not independently verified. Reload starts a new session rather than enforcing a permanent learner failure count.
diff --git a/docs/ai-literacy/capstone.js b/docs/ai-literacy/capstone.js
new file mode 100644
index 0000000..b6e72aa
--- /dev/null
+++ b/docs/ai-literacy/capstone.js
@@ -0,0 +1,179 @@
+/* Fresh, reproducible fictional practice; no AI service, persistence or network. */
+(function () {
+ 'use strict';
+ function scenario(seed, variant = 0) {
+ let state = seed >>> 0;
+ const pick = n => { state = (Math.imul(1664525, state) + 1013904223) >>> 0; return state % n; };
+ const gardens = ['Prism Orchard', 'Velvet Conservatory', 'Silver Fern Dome'];
+ const halls = ['Echo Pavilion', 'Paper Moon Gallery', 'Amber Archive'];
+ const walks = ['Kite Ridge', 'Copper Boardwalk', 'Willow Loop'];
+ const kitchens = ['Clover Table', 'Pebble Pantry', 'Saffron Lantern'];
+ const names = [gardens[pick(3)], halls[pick(3)], walks[pick(3)]];
+ const kitchen = kitchens[pick(3)];
+ const prices = [8 + pick(10), 12 + pick(12), 1 + pick(7)];
+ const lunch = 4 + pick(7), shuttle = 2 * (6 + pick(9));
+ const perPerson = prices.reduce((a,b) => a+b,0) + 3*lunch + shuttle/2;
+ // Draw distinct upper bits: parity of consecutive LCG outputs would correlate errors.
+ const errorFlags = pick(1024) ^ (variant ? 56 : 0);
+ const closedVisit = Boolean(errorFlags & 8);
+ const ariPrinted = perPerson + ((errorFlags & 16) ? 2 + pick(7) : 0);
+ const partyPrinted = perPerson*2 + ((errorFlags & 32) ? 3 + pick(9) : 0);
+ const order = closedVisit ? [0,1,2] : [1,0,2];
+ const prompt = 'Plan Monday through Wednesday in fictional year F2 for two travelers, Ari and Bo. Use each attraction once and a nut-free lunch daily. Use only these vendors; show exact per-person and party totals including the shared shuttle. No other costs or travel-time constraints apply.';
+ const facts = [
+ names[0]+': '+prices[0]+' credits per person; closed Monday.',
+ names[1]+': '+prices[1]+' credits per person; closed Wednesday.',
+ names[2]+': '+prices[2]+' credits per person; unavailable Tuesday.',
+ kitchen+': nut-free lunch, '+lunch+' credits per person; open all three days.',
+ 'Shared three-day shuttle: '+shuttle+' credits for the party, split equally ('+shuttle/2+' each).'
+ ];
+ const days = ['Monday','Tuesday','Wednesday'];
+ const response = days.map((day,i) => day+': '+names[order[i]]+'; '+kitchen+' lunch.').concat([
+ 'Ari full-trip total: '+ariPrinted+' credits.',
+ 'Bo full-trip total: '+perPerson+' credits.',
+ 'Full-trip party total: '+partyPrinted+' credits including the '+shuttle+'-credit shared shuttle.'
+ ]);
+ const criteria = [
+ {text:'States Ari’s full-trip total as exactly '+perPerson+' credits, including '+shuttle/2+' credits for the shuttle.', weight:2, origin:'explicit', pass:ariPrinted===perPerson, evidence:'The response prints '+ariPrinted+' credits for Ari; the expected total is '+perPerson+'.'},
+ {text:'States the full-trip party total as exactly '+perPerson*2+' credits, including the shared '+shuttle+'-credit shuttle.', weight:4, origin:'explicit', pass:partyPrinted===perPerson*2, evidence:'The response prints '+partyPrinted+' credits for the party; the expected total is '+perPerson*2+'.'},
+ {text:'Schedules '+names[0]+' on Monday, when it is closed.', weight:-6, origin:'explicit', pass:closedVisit, evidence:closedVisit ? 'Monday names '+names[0]+', triggering the closed-day penalty.' : 'Monday names '+names[1]+', so the closed-day penalty does not trigger.'}
+ ];
+ return {id:'F2-'+(seed>>>0).toString(16).padStart(8,'0')+'-A'+(variant+1),seed:seed>>>0,prompt,facts,response,criteria,perPerson,partyTotal:perPerson*2,score:criteria.reduce((sum,c)=>sum+(c.pass?c.weight:0),0)};
+ }
+ if (typeof module !== 'undefined' && module.exports) { module.exports = {scenario}; return; }
+ const root = document.getElementById('fresh-practice');
+ if (!root) return;
+ let exercise, stage, round, seed, history, rounds, completed;
+ const form = document.getElementById('capstone-form');
+ const question = document.getElementById('capstone-question');
+ const controls = document.getElementById('capstone-controls');
+ const feedback = document.getElementById('capstone-feedback');
+ const submit = document.getElementById('capstone-submit');
+ const next = document.getElementById('capstone-next');
+ const retry = document.getElementById('capstone-retry');
+ const appendText = (parent,tag,text) => { const element=document.createElement(tag); element.textContent=text;parent.append(element);return element; };
+ const cornell = 'https://teaching.cornell.edu/teaching-resources/assessing-student-learning/using-rubrics';
+ function renderQuestion() {
+ controls.replaceChildren(); feedback.textContent=''; submit.hidden=false; next.hidden=true;
+ if (stage < 3) {
+ const criterion = exercise.criteria[stage];
+ question.textContent='Attempt '+round+' of 2 · check '+(stage+1)+' of 3: '+criterion.text+' Weight '+(criterion.weight>0?'+':'')+criterion.weight+'; '+criterion.origin+'. Does this statement PASS or FAIL for the fictional response?';
+ ['PASS','FAIL'].forEach(value => {
+ const label=document.createElement('label');label.className='choice';
+ const input=document.createElement('input');input.type='radio';input.name='capstone-answer';input.value=value;input.required=true;
+ label.append(input,document.createTextNode(' '+value));controls.append(label);
+ });
+ } else {
+ question.textContent='Attempt '+round+' of 2 · final scoring step: add each signed weight only when its statement passes. What is this response’s total for the three criteria?';
+ const label=appendText(controls,'label','Raw score in points');label.htmlFor='capstone-total';
+ const input=document.createElement('input');input.type='number';input.step='1';input.required=true;input.id='capstone-total';controls.append(input);
+ }
+ }
+ function renderScenario() {
+ document.getElementById('capstone-id').textContent='Fictional scenario '+exercise.id+'. Attempt '+round+' of 2. Download its ID and facts to keep this practice evidence.';
+ const content=document.getElementById('capstone-scenario');content.replaceChildren();
+ appendText(content,'h3','Synthetic task prompt');appendText(content,'p',exercise.prompt);
+ appendText(content,'h3','Synthetic input facts');const facts=appendText(content,'ul','');exercise.facts.forEach(f=>appendText(facts,'li',f));
+ appendText(content,'h3','Fictional model response');const response=appendText(content,'ul','');exercise.response.forEach(r=>appendText(response,'li',r));
+ form.hidden=false;renderQuestion();
+ }
+ function fresh() {
+ seed=window.crypto.getRandomValues(new Uint32Array(1))[0];
+ exercise=scenario(seed);round=1;stage=0;history=[];rounds=[];completed=false;retry.hidden=true;
+ document.getElementById('capstone-progress').textContent='No assessment attempts completed in this page session.';
+ document.getElementById('capstone-results').replaceChildren();renderScenario();
+ }
+ form.addEventListener('submit',event=>{
+ event.preventDefault();
+ const value=stage<3 ? form.querySelector('input:checked')?.value : document.getElementById('capstone-total').value;
+ if(value === undefined || value === '') return;
+ const expected=stage<3 ? (exercise.criteria[stage].pass?'PASS':'FAIL') : exercise.score;
+ const correct=stage<3 ? value===expected : Number(value)===expected;
+ history.push({round,step:stage+1,answer:value,correct});
+ feedback.textContent='Answer recorded. Review and your scenario-based study guide appear after all four steps.';
+ submit.hidden=true; next.hidden=false;
+ document.getElementById('capstone-new').disabled=true;
+ controls.querySelectorAll('input').forEach(input=>input.disabled=true);
+ next.textContent=stage===3?'Finish this attempt':'Next scoring step';
+ });
+ function studyGuide(result) {
+ const box=document.getElementById('capstone-results');
+ appendText(box,'h3','Study guide for '+result.exercise.id);
+ const items=appendText(box,'ul','');
+ result.studyGuide=[];
+ result.answers.filter(a=>!a.correct).forEach(answer=>{
+ let explanation;
+ if(answer.step===1) explanation='Exact individual cost: add the three attraction prices, three lunches and half the shuttle. For your scenario, '+result.exercise.facts.slice(0,3).map(f=>f.match(/: (\d+)/)[1]).join(' + ')+' + three lunches + half the shuttle = '+result.exercise.perPerson+' credits. Compare this with the amount printed for Ari.';
+ else if(answer.step===2) explanation='Party total: two individual totals make '+result.exercise.partyTotal+' credits. Include the shared shuttle once. Compare that expected amount with the printed party total.';
+ else if(answer.step===3) explanation='Closed-day mistake: '+result.exercise.criteria[2].text+' A PASS on this statement means the mistake occurred and subtracts 6 points. A FAIL adds zero.';
+ else explanation='Weighted score: add each signed weight on PASS, zero on FAIL. For this response: '+result.exercise.criteria.map(c=>c.pass?c.weight:0).join(' + ')+' = '+result.exercise.score+' points. That score evaluates the fictional response, not you.';
+ result.studyGuide.push(explanation);
+ appendText(items,'li',explanation);
+ });
+ const p=appendText(box,'p','Read ');const link=appendText(p,'a','Cornell Center for Teaching Innovation: Using rubrics');link.href=cornell;
+ p.append(document.createTextNode(' for further study on measurable criteria, feedback and revising a rubric. This is a teaching resource, not an enrolled class or a program endorsement.'));
+ }
+ function alternativePaths() {
+ const box=document.getElementById('capstone-results');
+ appendText(box,'h3','Choose a next learning path');
+ appendText(box,'p','Two attempts did not yet meet this exercise’s four-check target. That is a reason to pause, study or explore another task; it does not establish whether you are suited for a job.');
+ const successes=history.filter(h=>h.correct);
+ const p=appendText(box,'p','');let label,href;
+ if(successes.some(h=>h.step===1||h.step===2)) {
+ p.append(document.createTextNode('You correctly compared at least one printed total with its expected value. Build on that observed number-checking skill with '));label='cost-comparison practice';href='../prompts/compare-costs.html';
+ } else if(successes.some(h=>h.step===3)) {
+ p.append(document.createTextNode('You correctly identified at least one closed-day rule outcome. Build on that observed rule-checking skill with '));label='source and information auditing';href='../prompts/audit-information.html';
+ } else if(successes.some(h=>h.step===4)) {
+ p.append(document.createTextNode('You correctly calculated at least one weighted total. Try applying that arithmetic in '));label='technology-planning exercises';href='../technology-planning/index.html';
+ } else {
+ p.append(document.createTextNode('These four checks did not show a clear strength. Choose an interest and a small task rather than treating the result as a verdict: '));label='explore creative and technology tracks';href='../tracks/index.html';
+ }
+ rounds[rounds.length-1].nextPath={label,href};
+ const link=appendText(p,'a',label);link.href=href;p.append(document.createTextNode('. These are learning suggestions, not assessments of abilities the exercise did not test.'));
+ appendText(box,'p','You can return to the lessons or ask for human feedback. The two-attempt record applies to this page session only; download it before leaving if you want to discuss it with PIXIE.');
+ }
+ function finish() {
+ form.hidden=true;
+ const answers=history.filter(h=>h.round===round),correct=answers.filter(h=>h.correct).length;
+ const result={round,exercise,answers,correct,passed:correct===4};rounds.push(result);
+ const box=document.getElementById('capstone-results');box.replaceChildren();
+ document.getElementById('capstone-progress').textContent='Attempt '+round+': '+correct+'/4 correct; '+(result.passed?'practice target met.':'practice target not met.');
+ appendText(box,'p','Fictional response weighted score: '+exercise.score+' points. Practice target: all three PASS/FAIL checks and the raw score correct (4/4). This local practice target is not a qualification threshold.');
+ const list=appendText(box,'ol','');exercise.criteria.forEach(c=>appendText(list,'li',(c.pass?'PASS':'FAIL')+'; '+c.weight+' weight; '+(c.pass?c.weight:0)+' points. '+c.evidence));
+ if(!result.passed) studyGuide(result);
+ if(!result.passed&&round===1) {
+ appendText(box,'p','Review this guide, then take your second attempt. It keeps your fictional prices and vendors but changes the response mistakes, so check the evidence again.');
+ retry.hidden=false;
+ } else {
+ completed=true;retry.hidden=true;
+ if(!result.passed) alternativePaths();
+ else appendText(box,'p','You met this practice target. Keep your record and one improvement, then choose another learning task or request human review. This is not certification or job eligibility.');
+ }
+ box.tabIndex=-1;box.focus();
+ }
+ next.addEventListener('click',()=>{
+ stage++;
+ if(stage<4) {renderQuestion();question.tabIndex=-1;question.focus();} else finish();
+ });
+ retry.addEventListener('click',()=>{
+ round=2;stage=0;exercise=scenario(seed,1);retry.hidden=true;
+ document.getElementById('capstone-results').replaceChildren();renderScenario();document.getElementById('capstone-id').focus();
+ });
+ function record() {
+ if(!exercise) return '';
+ const saved=rounds.slice();
+ if(!saved.some(result=>result.round===round)) {
+ const answers=history.filter(h=>h.round===round);
+ saved.push({round,exercise,answers,correct:answers.filter(h=>h.correct).length,passed:false});
+ }
+ const sections=saved.map(result=>'\n### Attempt '+result.round+' · '+result.exercise.id+'\n'+result.exercise.prompt+'\n\nInput facts:\n'+result.exercise.facts.map(f=>'- '+f).join('\n')+'\n\nFictional response:\n'+result.exercise.response.map(f=>'- '+f).join('\n')+'\n\nExplicit criteria and answer key:\n'+result.exercise.criteria.map(c=>'- '+c.text+' Weight '+c.weight+'; '+(c.pass?'PASS':'FAIL')+'; '+(c.pass?c.weight:0)+' points. '+c.evidence).join('\n')+'\n\nAnswers:\n'+result.answers.map(h=>'Step '+h.step+': '+h.answer+'; '+(h.correct?'correct':'incorrect')).join('\n')+'\nPractice target: '+result.correct+'/4; '+(result.passed?'met':'not yet met or incomplete')+'\nFictional response weighted score: '+result.exercise.score+'\n\nScenario study guide:\n'+(result.studyGuide||[]).map(note=>'- '+note).join('\n')+'\nNext learning path: '+(result.nextPath?result.nextPath.label+' ('+result.nextPath.href+')':result.passed?'Choose another task or human review':'Study, then use the second attempt if available')+'\n');
+ return '\n## Fresh synthetic classroom practice\nSeed: '+seed+'\nStatus: '+(completed?'finished':'in progress')+'\n'+sections.join('\n')+'\nLearner-produced local practice record; not independently verified, accepted project work, certification or job suitability.\n\nFurther study: Cornell Using rubrics — '+cornell+'\n\n### One improvement after feedback\n[Describe what you changed and why before sharing.]\n';
+ }
+ document.addEventListener('training-artifact-request',event=>{event.detail.sections.push(record());});
+ document.getElementById('capstone-download').addEventListener('click',()=>{
+ const url=URL.createObjectURL(new Blob(['# Synthetic classroom practice\n'+record()],{type:'text/markdown'}));
+ const link=document.createElement('a');link.href=url;link.download='synthetic-classroom-'+exercise.id+'.md';link.click();setTimeout(()=>URL.revokeObjectURL(url),1000);
+ });
+ document.getElementById('capstone-new').addEventListener('click',()=>{fresh();document.getElementById('capstone-id').focus();});
+ fresh();root.hidden=false;
+})();
diff --git a/docs/ai-literacy/data/labor-market.json b/docs/ai-literacy/data/labor-market.json
new file mode 100644
index 0000000..8724066
--- /dev/null
+++ b/docs/ai-literacy/data/labor-market.json
@@ -0,0 +1,50 @@
+{
+ "schemaVersion": 1,
+ "version": "2026-11-07",
+ "metric": "Projected percent change in employment",
+ "geography": "United States",
+ "population": "Wage and salary employment across all industries plus self-employment in each named occupation or occupational group",
+ "observationPeriod": {
+ "base": 2024,
+ "projection": 2034
+ },
+ "units": "percent",
+ "retrievedOn": "2026-11-07",
+ "lastVerified": "2026-11-07",
+ "verificationMethod": "Original publisher pages retrieved with connected web research tool; chart data checked against values below.",
+ "refresh": "Manual source review through a reviewed pull request; no automatic refresh.",
+ "records": [
+ {
+ "occupation": "Computer and mathematical occupations",
+ "code": "15-0000",
+ "value": 10.1,
+ "sourceUrl": "https://www.bls.gov/opub/mlr/2026/article/industry-and-occupational-employment-projections-overview.htm",
+ "publicationDate": "2026-01",
+ "sourceLocation": "Chart 3; occupational employment table"
+ },
+ {
+ "occupation": "All occupations",
+ "code": "00-0000",
+ "value": 3.1,
+ "sourceUrl": "https://www.bls.gov/opub/ted/2026/artificial-intelligence-information-technology-and-employment-2024-34.htm",
+ "publicationDate": "2026-07-16",
+ "sourceLocation": "Selected occupations chart"
+ },
+ {
+ "occupation": "Data scientists",
+ "code": "15-2051",
+ "value": 33.5,
+ "sourceUrl": "https://www.bls.gov/opub/ted/2026/artificial-intelligence-information-technology-and-employment-2024-34.htm",
+ "publicationDate": "2026-07-16",
+ "sourceLocation": "Selected occupations chart"
+ },
+ {
+ "occupation": "Software developers",
+ "code": "15-1252",
+ "value": 15.8,
+ "sourceUrl": "https://www.bls.gov/opub/ted/2026/artificial-intelligence-information-technology-and-employment-2024-34.htm",
+ "publicationDate": "2026-07-16",
+ "sourceLocation": "Selected occupations chart"
+ }
+ ]
+}
diff --git a/docs/ai-literacy/index.html b/docs/ai-literacy/index.html
new file mode 100644
index 0000000..aac255c
--- /dev/null
+++ b/docs/ai-literacy/index.html
@@ -0,0 +1,5 @@
+
+
+Understand AI. Question the Output. Build a Skill. — Loptr Lab Training
+
+Skip to main content
LOPTR LAB / AI LITERACY
Understand AI. Question the Output. Build a Skill.
AI Literacy: Learn to Question, Test, and Evaluate AI
AI is changing how people research, create, communicate, and work. Using it effectively involves more than writing prompts: you need to check its results.
This free introductory class teaches one practical skill: writing clear criteria to evaluate AI-generated responses. You do not need to become an AI engineer to understand what AI does or recognize its limitations.
No programming experience is required. Explore without an account or job application. Work at your own pace on a phone, tablet or computer; a paid subscription is unnecessary.
Explain a model in everyday language and distinguish prompts, input files, responses and rubrics.
Identify limitations and misleading AI claims.
Write atomic, verifiable, objective and self-contained PASS/FAIL criteria.
Choose positive and negative weights and distinguish explicit from implicit requirements.
Score fictional work using evidence and explain one improvement.
Understand how evaluation relates to different kinds of AI-assisted work.
What does a model do?
A model is software trained to find patterns in examples. A text-generating model uses patterns and the context you supply to produce a response, one piece of text at a time. It can draft, summarize and transform information. A fluent response can still contain invented details or mistakes.
Prompt
The instruction or question you give the model.
Input file
Material supplied with a task, such as a fictional price list.
Model response
The generated answer or deliverable you inspect.
Rubric
A set of criteria: clear rules for deciding whether the response meets requirements.
Evaluation
Checking output against those rules and recording evidence.
Hallucination
A generated claim that sounds plausible but is unsupported or false.
Start by checking names, numbers and citations against the task facts. OpenAI’s evaluation guidance explains why repeatable tests and human judgment matter.
What people hear about AI — and what the evidence actually shows
“AI knows everything.”
Models have limits in training, context and access to current sources. A tool connection can help retrieve information, but still needs checking.
This class uses careful reading and writing. Certain evaluation or quality-review tasks use research or domain knowledge; employer and project requirements vary.
AI-assisted work includes writing, research, education and quality review alongside specialized technical careers. Some roles require advanced credentials.
Try it: A teacher can review whether a generated lesson meets a learning objective. Teacher skills and rubrics.
“AI is replacing every job.”
Tasks and occupations differ. BLS projects growth in some occupations and declines in others; a projection is not a guarantee.
Try it: Software developers and customer service representatives have different projected trends. BLS occupational projections.
“AI will automatically create new opportunities for everyone.”
Access, training and job changes are uneven. Stanford reports early-career employment declines in some AI-exposed work, with limitations in the data.
“You need expensive equipment or a paid subscription to learn AI.”
You can complete this lesson with the fictional response on the page, without calling any AI service. Other courses or tools may have different requirements.
Try it: Grade the supplied response on your current device, or write your criteria on paper. Free practice in this class.
“An AI-generated answer is correct because it sounds convincing.”
Writing style is not evidence of accuracy. Use specific tests and inspect supporting facts.
Try it: A polished itinerary still fails if it schedules a visit on a closure day. Evaluation best practices.
AI and Work: What the Data Tells Us
United States · projected employment change, 2024–2034. These percentages compare expected employment in 2034 with employment in 2024. They are not counts of current AI vacancies, and these occupations include work beyond AI.
Static reviewed snapshot, verified 7 November 2026. Check source dates before relying on it.
Population: U.S. wage and salary employment across industries plus self-employment. BLS published the overview in January 2026 and the selected-occupations article on 16 July 2026. The snapshot is periodically reviewed, not live or real-time.
BLS also projects declines for some administrative and customer-service occupations. Its long-term projections do not predict an individual’s job outcome.
Contrasting evidence:Stanford’s 21 October 2026 report describes falling employment among young workers in highly AI-exposed software-development and customer-service work. The underlying payroll data do not represent every worker, and association with AI exposure alone does not prove AI caused a change. Monthly observations and decade-long projections answer different questions.
Different kinds of change: automation hands a task to software; augmentation helps a person do it. Existing occupations may acquire checking responsibilities. Specialized AI careers can require advanced study. Entry-level evaluation tasks may emphasize careful reading, writing or subject knowledge; availability and requirements vary.
For further context, explore the Stanford AI Index and Lightcast’s job-posting analysis. Postings measure advertised demand, not completed hires or guaranteed openings. These sources do not endorse this class.
Links and descriptions checked 7 November 2026. Start with this class before the technical references. External organizations are reference providers, not partners.
Cornell: Using rubrics — Beginner. A teaching guide to measurable criteria, feedback and revision; not an enrolled class.
OpenAI Evaluation Best Practices — Intermediate. Concepts for designing tests; API examples are optional. This class does not use its hosted Evals platform.
Optional examples: check a PIXIE handoff for stated next actions; evaluate a synthetic educational exercise for 50 Ways to Leave Another; verify a Made-Sick resource description against its cited source; or check Duet and game documentation against specified rules. These are contexts for practice, not new integrations or assignments.
Use the existing portfolio-evidence workflow to explain your own contribution. GitHub remains the shared record; no second tracker is needed.
Interested in Exploring AI-Related Work?
Some organizations offer paid projects involving AI evaluation, research, writing, and specialist knowledge. Opportunities vary by location, experience, availability, and project requirements.
Handshake is one place to explore potential opportunities. Applying is optional, and completing this class does not guarantee acceptance or paid work.
Referral disclosure: This is a referral link. Loptr Lab's founder may receive compensation if an eligible referral completes qualifying paid work. You are not required to use this link or apply to participate in the training.
Before applying, check Handshake’s current referral conditions and the requirements of the specific project. Referral rewards are separate from learner compensation. Loptr Lab does not represent itself as an authorized Handshake training provider or recruiting partner.
\ No newline at end of file
diff --git a/docs/ai-literacy/practice-artifact.md b/docs/ai-literacy/practice-artifact.md
new file mode 100644
index 0000000..190f61a
--- /dev/null
+++ b/docs/ai-literacy/practice-artifact.md
@@ -0,0 +1,39 @@
+# Synthetic rubric practice artifact
+
+Exercise only; not certification or accepted project work.
+Use fictional task facts, never learner records.
+
+## Synthetic task prompt
+Copy the Luma Quay task from rubrics.html, or write a fully fictional task.
+
+## Synthetic input facts
+Include every vendor, closure, blackout, price, restriction and exact expected calculation needed to grade.
+
+## Three rubric criteria
+For each: one self-contained PASS/FAIL check; signed nonzero weight; explicit/implicit classification; reason for the weight and origin.
+1. [Criterion; weight; classification; reason]
+2. [Criterion; weight; classification; reason]
+3. [Criterion; weight; classification; reason]
+
+## Fictional deliverable
+Copy deliverable C or write a fictional response. Label it as fictional.
+
+## Scoring and evidence
+For each criterion: PASS/FAIL; exact evidence; signed points awarded.
+PASS adds the signed weight; FAIL adds zero. A PASS on a negative criterion triggers its penalty.
+Total: [calculate]. Note requirements your three checks do not cover.
+
+## One improvement after feedback
+Before:
+Feedback:
+After:
+Why this is a stronger check:
+
+## Optional public contribution record
+Artifact link:
+Own contribution:
+What I checked:
+Observed outcome and limitations:
+Next action:
+
+Review visibility and attribution before posting. Continue in your existing PIXIE/GitHub checkpoint; no second tracker is required.
diff --git a/docs/ai-literacy/rubrics.html b/docs/ai-literacy/rubrics.html
new file mode 100644
index 0000000..1551dd1
--- /dev/null
+++ b/docs/ai-literacy/rubrics.html
@@ -0,0 +1,5 @@
+
+
+Write a rubric. Test the response. — Loptr Lab Training
+
+Skip to main content
LOPTR LAB / AI LITERACY
Write a rubric. Test the response.
Eight short steps, at your own pace
Each step gives an explanation and example, then asks one question. Use the fictional task below throughout. With JavaScript enabled, answer checking offers one retry and then an explanation. Nothing is sent to a model or server.
Without JavaScript, use the worked examples and “Answer and takeaway” sections. Open-ended writing uses a self-review checklist; automatic hints cannot certify the quality of a rubric. Write on paper if you prefer.
Your fictional task and input file
Everything below is fictional. Luma Quay, all vendors, identifiers, rates and rules are invented for this lesson.
Synthetic task prompt
Create an itinerary for two travelers, Ari and Bo, for Monday 8 June through Wednesday 10 June in fictional year F1. Include one attraction and one lunch each day, use each attraction once, and use only the supplied vendors. Both travelers require nut-free meals. Show each traveler’s total and the party total, including the shared shuttle. Budget: at most 100 credits for the party.
Synthetic input facts
Glass Garden: 10 credits per person; closed Monday.
Lantern Hall: 15 credits per person; closed Wednesday.
Cloud Walk: free; unavailable Tuesday (a blackout date).
Moss Kitchen: nut-free lunch, 5 credits per person; open all three days.
Ember Café: lunch, 4 credits per person; contains nuts. It cannot meet this task’s meal requirement.
One shuttle pass for all three days costs 20 credits for the party. Allocate 10 credits to each traveler.
No other costs, taxes, tips, discounts, travel-time constraints or reservations apply. Each attraction and lunch takes place within that day.
Complete fictional deliverable A
Monday 8 June: Lantern Hall; lunch at Moss Kitchen.
Tuesday 9 June: Glass Garden; lunch at Moss Kitchen.
Wednesday 10 June: Cloud Walk; lunch at Moss Kitchen.
Ari: 10 + 15 + 0 + (3 × 5) + 10 = 50 credits.
Bo: 10 + 15 + 0 + (3 × 5) + 10 = 50 credits.
Party: 50 + 50 = 100 credits, including the shared 20-credit shuttle.
Attractions: 25 per person, 50 party. Lunches: 15 per person, 30 party. Shuttle: 10 per person, 20 party. Total: 50 per person, 100 party.
1. Warm-up: the four parts
A prompt asks for an itinerary; the input file supplies prices; the response is the itinerary; the rubric checks it. Example: “Party total is exactly 100 credits” is a rubric criterion.
Answer and takeaway
The price list supplies facts to the task; it is the input file.
Takeaway: Keep instructions, evidence, response and grading rules distinct.
2. Four principles
Atomic means one check. Verifiable means PASS/FAIL from the deliverable alone. Objective means a rule rather than personal taste. Self-contained means all grading facts are in the criterion. Example: “States the full-trip party total as exactly 100 credits, including the shared 20-credit shuttle.”
Answer and takeaway
The exact total supplies a single observable rule and its expected value. “Delightful” is subjective; “match the file” requires an external lookup.
Takeaway: A reviewer should not have to guess what PASS means.
3. Practice A: diagnose a flawed criterion
Flawed: “Lists a nut-free lunch and states the correct party total.” Two things can succeed or fail independently. Example correction for the first check: “Lists Moss Kitchen for Monday lunch; Moss Kitchen is nut-free.”
Answer and takeaway
Atomic fails: lunch choice and arithmetic are separate checks. Write a second criterion with the exact 100-credit party total.
Takeaway: Split checks that can have different outcomes.
4. Practice B: rewrite
Flawed: “The cost looks reasonable.” It uses an opinion and hides the expected value. Worked rewrite: “States Ari’s full-trip total as exactly 50 credits, including 10 credits for the shuttle.”
Answer and takeaway
Use the exact expected 100-credit party total and include the shuttle fact. No taste judgment or source lookup is needed.
Takeaway: Replace vague praise with a specific observable value.
5. Practice C: assign and justify weights
Positive weights reward fulfilled requirements. Negative weights penalize a defined mistake when that mistake is present. A PASS on a negative criterion triggers the penalty. Example: “Schedules any Ember Café lunch, whose meals contain nuts” has weight −6; a consistent currency label earns +1. Dietary compliance has higher stakes here. Explicit requirements come directly from the prompt or input; implicit requirements are necessary inferences, such as consistent units.
Answer and takeaway
Penalize the defined nut-containing meal mistake; reward consistent units modestly. Weights express task stakes, not equal-sized boxes.
Takeaway: Define the negative trigger before assigning its penalty.
6. Practice D: split without changing total weight
Flawed +6 criterion: “Lists Lantern Hall on Monday and Glass Garden on Tuesday.” Split into two self-contained checks: Lantern Hall on Monday, when open (+3); Glass Garden on Tuesday, when open (+3). The sum remains +6. Splitting allows partial credit when only one part passes.
Answer and takeaway
3 + 3 = 6. The other splits double or increase the weight. Preserve the total, while recognizing partial credit changes.
Takeaway: Split the requirement and preserve the weight budget.
7. Practice E: exclude an unverifiable criterion
Flawed: “The assistant checked every vendor’s live website before answering.” The itinerary does not prove an unseen browsing action. Replace process guesses with output checks: “Does not schedule Cloud Walk on Tuesday, when it is unavailable.”
Answer and takeaway
Exclude it from this output rubric. A process audit would need separately authorized evidence; do not infer hidden activity from polished writing.
Takeaway: Grade observable output; do not invent evidence of hidden work.
How weighted PASS/FAIL scoring works
Teaching rubric: eight checks, 18 possible positive points
Single check
Weight
Origin
Deliverable A evidence
Lists Lantern Hall on Monday 8 June, when it is open.
+3
Explicit
PASS: Monday names Lantern Hall.
Lists Glass Garden on Tuesday 9 June, when it is open.
+3
Explicit
PASS: Tuesday names Glass Garden.
Lists Cloud Walk on Wednesday 10 June, outside its Tuesday blackout.
+3
Explicit
PASS: Wednesday names Cloud Walk.
States Ari’s full-trip total as exactly 50 credits, including 10 credits for the shuttle.
+2
Explicit
PASS: Ari’s total is 50.
States Bo’s full-trip total as exactly 50 credits, including 10 credits for the shuttle.
+2
Explicit
PASS: Bo’s total is 50.
States the full-trip party total as exactly 100 credits, including the shared 20-credit shuttle.
+4
Explicit
PASS: party total is 100.
Uses the same currency label, credits, for every stated monetary total.
+1
Implicit
PASS: every monetary total uses credits.
Schedules at least one lunch at Ember Café, whose meals contain nuts.
−6
Explicit
FAIL: no Ember Café lunch is scheduled; no penalty.
For each criterion, PASS means its statement is true. Add its weight on PASS; add zero on FAIL. Deliverable A earns 3 + 3 + 3 + 2 + 2 + 4 + 1 + 0 = 18 points. The negative criterion is a defined mistake: it fails here, so the penalty does not apply. Raw scores can be negative; this exercise has a −6 minimum and +18 maximum, not a certification threshold.
Fictional deliverable B: spot the failures
Keep A’s attractions and printed costs unchanged, but change Tuesday lunch to Ember Café. The printed Ari total is still 50, Bo 50 and party 100 credits. This is deliberately flawed: the meal violates the restriction and the printed costs no longer match its choices.
Under these eight checks, all seven positive statements remain true and the negative statement now passes: 18 − 6 = 12 points. That does not make B acceptable. This teaching rubric does not check every requirement or recalculate every possible itinerary. Add separate arithmetic-consistency and daily nut-free-lunch checks for a full evaluation. Critical requirements can also be hard gates, independent of score.
Advanced example: the existing Veiled Dominion reviewer scorecard uses weighted 1–5 dimensions and hard gates. Some broad dimensions combine judgments; they differ from the strict atomic PASS/FAIL rules taught here.
Score answer
12 points. Subtract 6 once; do not turn a penalty into a reward.
8. Wrap-up: write three criteria
Now write your own three single-check criteria for deliverable A. Each needs a signed weight and an explicit/implicit label. Example: “States Bo’s full-trip total as exactly 50 credits, including 10 credits for the shuttle” (+2, explicit). Choose three different checks and explain their stakes.
Below, write one criterion at a time. Hints flag possible issues with wording; they do not understand meaning or decide PASS/FAIL. After one revision, use the self-review checklist and examples to improve your draft.
Targeted self-review
Atomic: could part pass while another fails? Split those checks and preserve their combined weight.
Verifiable: can you point to exact words or omissions in the response? Exclude unseen actions.
Objective: replace “good,” “reasonable” and similar opinions with an exact rule.
Self-contained: include the expected amount, date, vendor restriction or other needed fact in the criterion.
Weights: explain the stakes; a negative weight needs a precisely defined mistake.
Origin: name the prompt/input fact or explain the necessary inference.
Independent exercise: fictional deliverable C swaps A’s Monday and Tuesday attractions: Monday Glass Garden; Tuesday Lantern Hall; Wednesday Cloud Walk. All lunches are Moss Kitchen and totals remain 50 per traveler, 100 party. Score your three criteria against C. Record PASS/FAIL and the exact evidence, then rewrite one weak criterion. For a negative criterion, PASS means its mistake occurred.
Independent exercise feedback
Glass Garden is closed Monday. Under the eight-check teaching rubric, the Monday Lantern Hall and Tuesday Glass Garden checks both fail; the other positive checks pass and the meal penalty does not trigger. Score: 18 − 3 − 3 = 12. Your three-criterion score depends on the checks you wrote; explain each outcome rather than borrowing this total.
Takeaway: a useful rubric makes a specific failure visible and supports a concrete revision.
Finish with a fresh scenario and scoring record
The worked examples above stay available for learning. This final exercise varies the fictional vendors, prices and mistakes each time you open the page. Calculate the totals, then score three checks one at a time. The generated arithmetic and answer key follow fixed rules. You have two assessment attempts, each with four checks; the practice target is 4/4. After the first unsuccessful attempt, study feedback tied to your scenario before trying a changed response with the same facts. After a second unsuccessful attempt, explore further study and a path based on the checks you answered well. These are learning suggestions, not job-suitability decisions.
Use the record with PIXIE in the classroom pilot
Ask PIXIE: “Help me review my synthetic scenario, three criteria, first-attempt answers, retries, final scoring and one improvement. Identify the next useful practice step. Keep it as a draft for my existing Training checkpoint.” The download includes the scenario facts and scoring history so a new session can use evidence rather than memory.
Review visibility and attribution before sharing through your existing GitHub issue. The record is learner-reported practice; PIXIE does not automatically receive, save or verify classroom progress. Keep private learner and academic records out of public checkpoints. No new classroom tracker is created.
Keep a shareable practice artifact
Use the synthetic practice-artifact template. Include your prompt, input facts, three criteria, weights, classifications, fictional response, PASS/FAIL evidence and one improvement made after feedback.
Your entries stay in this page’s memory and are erased on reload or reset. Download only if you choose; do not enter personal, employment, medical, academic or financial records.
Sharing is optional. Follow the existing contribution and portfolio workflow. Review your artifact and attribution before submitting through your own GitHub account: issues and comments are public. Keep your existing checkpoint URL and add progress there; an exercise is not maintainer acceptance, certification or membership.
\ No newline at end of file
diff --git a/docs/ai-literacy/rubrics.js b/docs/ai-literacy/rubrics.js
new file mode 100644
index 0000000..50186ae
--- /dev/null
+++ b/docs/ai-literacy/rubrics.js
@@ -0,0 +1,152 @@
+/* Deterministic local practice. No model calls, network, or saved learner records. */
+(() => {
+'use strict';
+const questions = [
+ {
+ "correct": 1,
+ "answer": "The price list supplies facts to the task; it is the input file.",
+ "takeaway": "Keep instructions, evidence, response and grading rules distinct.",
+ "principle": "Verifiable"
+ },
+ {
+ "correct": 2,
+ "answer": "The exact total supplies a single observable rule and its expected value. \u201cDelightful\u201d is subjective; \u201cmatch the file\u201d requires an external lookup.",
+ "takeaway": "A reviewer should not have to guess what PASS means.",
+ "principle": "Objective / self-contained"
+ },
+ {
+ "correct": 0,
+ "answer": "Atomic fails: lunch choice and arithmetic are separate checks. Write a second criterion with the exact 100-credit party total.",
+ "takeaway": "Split checks that can have different outcomes.",
+ "principle": "Atomic"
+ },
+ {
+ "correct": 1,
+ "answer": "Use the exact expected 100-credit party total and include the shuttle fact. No taste judgment or source lookup is needed.",
+ "takeaway": "Replace vague praise with a specific observable value.",
+ "principle": "Objective / self-contained"
+ },
+ {
+ "correct": 0,
+ "answer": "Penalize the defined nut-containing meal mistake; reward consistent units modestly. Weights express task stakes, not equal-sized boxes.",
+ "takeaway": "Define the negative trigger before assigning its penalty.",
+ "principle": "Weight direction / stakes"
+ },
+ {
+ "correct": 1,
+ "answer": "3 + 3 = 6. The other splits double or increase the weight. Preserve the total, while recognizing partial credit changes.",
+ "takeaway": "Split the requirement and preserve the weight budget.",
+ "principle": "Weight conservation"
+ },
+ {
+ "correct": 2,
+ "answer": "Exclude it from this output rubric. A process audit would need separately authorized evidence; do not infer hidden activity from polished writing.",
+ "takeaway": "Grade observable output; do not invent evidence of hidden work.",
+ "principle": "Verifiable"
+ }
+];
+document.querySelectorAll('.rubric-question').forEach(form => {
+ const q = questions[Number(form.dataset.step) - 1];
+ let attempts = 0;
+ const feedback = form.querySelector('.feedback');
+ form.addEventListener('submit', event => {
+ event.preventDefault();
+ const answer = form.querySelector('input:checked');
+ if (!answer) return;
+ attempts++;
+ const correct = Number(answer.value) === q.correct;
+ if (correct || attempts >= 2) {
+ feedback.textContent = (correct ? 'PASS. ' : 'After your retry: ') + q.answer + ' Takeaway: ' + q.takeaway;
+ form.querySelector('button[type=submit]').disabled = true;
+ } else {
+ feedback.textContent = 'Revisit ' + q.principle + '. ' + q.takeaway + ' Try once more.';
+ }
+ });
+ form.querySelector('.question-reset').addEventListener('click', () => {
+ form.reset(); attempts = 0; feedback.textContent = '';
+ form.querySelector('button[type=submit]').disabled = false;
+ });
+});
+const score = document.getElementById('score-practice');
+let scoreAttempts = 0;
+score.addEventListener('submit', event => {
+ event.preventDefault(); scoreAttempts++;
+ const correct = Number(document.getElementById('score-answer').value) === 12;
+ document.getElementById('score-feedback').textContent = correct || scoreAttempts >= 2
+ ? (correct ? 'PASS. ' : 'After your retry: ') + '18 + (−6) = 12 points. Takeaway: a mistake triggers its negative weight.'
+ : 'Weight direction: a negative criterion subtracts points when its defined mistake occurs. Try once more.';
+ if (correct || scoreAttempts >= 2) score.querySelector('button[type=submit]').disabled = true;
+});
+score.addEventListener('reset', () => {
+ scoreAttempts = 0; document.getElementById('score-feedback').textContent = '';
+ score.querySelector('button[type=submit]').disabled = false;
+});
+const writer = document.getElementById('writer');
+const text = document.getElementById('criterion-text');
+const weight = document.getElementById('criterion-weight');
+const origin = document.getElementById('criterion-origin');
+const reason = document.getElementById('criterion-reason');
+const feedback = document.getElementById('writer-feedback');
+const keep = document.getElementById('keep-criterion');
+const review = document.getElementById('review-criterion');
+let drafts = [], reviews = 0;
+function hints(value, signedWeight) {
+ const result = [];
+ if (/\b(and|also|as well as)\b/i.test(value)) result.push('Atomic: you may have combined checks. Can each part pass separately?');
+ if (/\b(good|nice|reasonable|beautiful|delightful|appropriate|clear|correct)\b/i.test(value)) result.push('Objective: replace judgment words with an exact observable rule.');
+ if (/\b(file|source|above|provided|website|browsed|researched|thought)\b/i.test(value)) result.push('Verifiable/self-contained: include the grading facts here and remove claims about unseen actions.');
+ if (!/\d|Moss|Ember|Lantern|Glass|Cloud|credits|Monday|Tuesday|Wednesday/i.test(value)) result.push('Self-contained: add a concrete expected fact, such as 100 credits for the party including the shuttle.');
+ if (signedWeight < 0) result.push('Negative weight: does PASS mean a specific mistake occurred? State that trigger explicitly.');
+ return result;
+}
+writer.addEventListener('submit', event => {
+ event.preventDefault();
+ weight.setCustomValidity(Number(weight.value) === 0 ? 'Choose a nonzero weight.' : '');
+ if (!writer.reportValidity()) return;
+ reviews++;
+ const notes = hints(text.value, Number(weight.value));
+ feedback.textContent = 'Wording hints only; no quality grade. ' + (notes.length ? notes.join(' ') : 'No keyword flags. That does not establish that your criterion meets the four principles.') + (reviews === 1 ? ' Revise once, or keep your draft and self-review.' : ' Worked reference: “States the full-trip party total as exactly 100 credits, including the shared 20-credit shuttle” (+4, explicit). Compare your own check with all four principles.');
+ keep.hidden = false;
+ review.textContent = 'Review my revision';
+ if (reviews >= 2) review.disabled = true;
+});
+weight.addEventListener('input', () => weight.setCustomValidity(''));
+keep.addEventListener('click', () => {
+ weight.setCustomValidity(Number(weight.value) === 0 ? 'Choose a nonzero weight.' : '');
+ if (!writer.reportValidity()) return;
+ drafts.push({ criterion: text.value.trim(), weight: Number(weight.value), origin: origin.value, reason: reason.value.trim() });
+ const item = document.createElement('p');
+ item.textContent = 'Draft ' + drafts.length + ': ' + text.value + ' (' + weight.value + ', ' + origin.value + '). Reason: ' + reason.value;
+ document.getElementById('written-criteria').append(item);
+ writer.reset(); reviews = 0; keep.hidden = true; review.disabled = false;
+ review.textContent = 'Get wording hints'; feedback.textContent = '';
+ if (drafts.length === 3) {
+ writer.hidden = true;
+ const done = document.createElement('p'); done.tabIndex = -1;
+ done.textContent = 'Three drafts captured. Now score deliverable C, record evidence, and document one revision in your artifact. Use “Reset my drafts” below to start again.';
+ document.getElementById('written-criteria').append(done); done.focus();
+ } else {
+ document.getElementById('writer-progress').textContent = 'Criterion ' + (drafts.length + 1) + ' of 3'; text.focus();
+ }
+});
+function resetDrafts() {
+ drafts = []; reviews = 0; writer.hidden = false; writer.reset(); weight.setCustomValidity('');
+ document.getElementById('written-criteria').replaceChildren();
+ document.getElementById('writer-progress').textContent = 'Criterion 1 of 3';
+ feedback.textContent = ''; keep.hidden = true; review.disabled = false;
+ review.textContent = 'Get wording hints'; text.focus();
+}
+document.getElementById('reset-writer').addEventListener('click', resetDrafts);
+const resetAllDrafts = document.createElement('button'); resetAllDrafts.type = 'button';
+resetAllDrafts.textContent = 'Reset my drafts'; resetAllDrafts.addEventListener('click', resetDrafts);
+document.getElementById('written-criteria').after(resetAllDrafts);
+document.getElementById('download-drafts').addEventListener('click', () => {
+ const sourceExercise = "Synthetic task prompt\nCreate an itinerary for two travelers, Ari and Bo, for Monday 8 June through Wednesday 10 June in fictional year F1. Include one attraction and one lunch each day, use each attraction once, and use only the supplied vendors. Both travelers require nut-free meals. Show each traveler\u2019s total and the party total, including the shared shuttle. Budget: at most 100 credits for the party.\nSynthetic input facts\nGlass Garden: 10 credits per person; closed Monday.\nLantern Hall: 15 credits per person; closed Wednesday.\nCloud Walk: free; unavailable Tuesday (a blackout date).\nMoss Kitchen: nut-free lunch, 5 credits per person; open all three days.\nEmber Caf\u00e9: lunch, 4 credits per person; contains nuts. It cannot meet this task\u2019s meal requirement.\nOne shuttle pass for all three days costs 20 credits for the party. Allocate 10 credits to each traveler.\nNo other costs, taxes, tips, discounts, travel-time constraints or reservations apply. Each attraction and lunch takes place within that day.\nComplete fictional deliverable A\nMonday 8 June: Lantern Hall; lunch at Moss Kitchen.\nTuesday 9 June: Glass Garden; lunch at Moss Kitchen.\nWednesday 10 June: Cloud Walk; lunch at Moss Kitchen.\nAri: 10 + 15 + 0 + (3 \u00d7 5) + 10 = 50 credits.\nBo: 10 + 15 + 0 + (3 \u00d7 5) + 10 = 50 credits.\nParty: 50 + 50 = 100 credits, including the shared 20-credit shuttle.\nAttractions: 25 per person, 50 party. Lunches: 15 per person, 30 party. Shuttle: 10 per person, 20 party. Total: 50 per person, 100 party.";
+ const content = '# Synthetic AI rubric practice artifact\n\nExercise only; not certification or accepted project work.\n\n## Synthetic prompt and input facts\n' + sourceExercise + '\n\n## My three criteria\n' + drafts.map((d,i) => (i+1)+'. '+d.criterion+'\nWeight: '+d.weight+'; '+d.origin+'\nReason: '+d.reason+'\nPASS/FAIL on C: [fill in]\nExact evidence: [fill in]\n').join('\n') + '\n## Fictional deliverable\nDeliverable C: Monday Glass Garden; Tuesday Lantern Hall; Wednesday Cloud Walk. Moss Kitchen lunch daily. Printed totals: Ari 50 credits; Bo 50 credits; party 100 credits including the shared 20-credit shuttle. Glass Garden is closed Monday.\n\n## Scoring\nFor each PASS add its signed weight; FAIL adds zero. Total: [calculate]\n\n## One improvement after feedback\nBefore: [fill in]\nAfter: [fill in]\nWhy: [fill in]\n\nReview all placeholders and public visibility before sharing.\n';
+ const extra = {sections: []};
+ document.dispatchEvent(new CustomEvent('training-artifact-request', {detail: extra}));
+ const url = URL.createObjectURL(new Blob([content, ...extra.sections], {type:'text/markdown'}));
+ const link = document.createElement('a'); link.href = url; link.download = 'synthetic-rubric-practice.md'; link.click();
+ setTimeout(() => URL.revokeObjectURL(url), 1000);
+});
+})();
diff --git a/docs/ai-literacy/snapshot.js b/docs/ai-literacy/snapshot.js
new file mode 100644
index 0000000..95249fd
--- /dev/null
+++ b/docs/ai-literacy/snapshot.js
@@ -0,0 +1,7 @@
+/* A dated static snapshot remains useful offline; no refresh request is made. */
+(() => {
+ 'use strict';
+ const verified = Date.UTC(2026, 10, 7);
+ const days = Math.max(0, Math.floor((Date.now() - verified) / 86400000));
+ document.getElementById('snapshot-age').textContent = 'Static snapshot verified 7 November 2026 (' + days + ' days ago). ' + (days > 180 ? 'This snapshot is over 180 days old; check the linked sources for newer evidence.' : 'Check source dates before relying on it.');
+})();
diff --git a/docs/index.html b/docs/index.html
index d363336..a72978d 100644
--- a/docs/index.html
+++ b/docs/index.html
@@ -69,6 +69,7 @@