08. Jurisdiction plugins
Draft 0.1. Reference implementation: shared/gradRules/ (eleven modules), shared/artifactRendererHtml.js (the RENDERERS registry and renderArtifactHtml), shared/reviewedAsOf.js, shared/nyCompliance.js, api/family/generate-artifact.js, shared/portraitTaxonomy.js (section 8.7).
8.1 Why plugins
The Record is above any jurisdiction. A state's graduation rule, a district's quarterly report, an ESA program's expense form: each is a read of the same record through a lens, and a render of that read into the paper a particular office asks for. Neither the read nor the render is the learner's identity, and neither ever alters the record or appears on a verifiable receipt. They are plugins: pure, cited, versioned, dated, replaceable.
Three plugin kinds exist today:
- rule sets (
shared/gradRules/*): deterministic evaluators that classify the record's rows against a published requirement and return a citation-rich reading; - artifact renderers (
shared/artifactRendererHtml.jsplus model builders such asshared/nyCompliance.js): pure functions from a render-agnostic model to a standalone printable HTML document; - competency taxonomies (
shared/portraitTaxonomy.js, section 8.7): the attribute vocabulary a jurisdiction adopted, as data, and the shape of a competency-evidence claim that names one attribute. Unlike the other two kinds, a taxonomy's claims render on verify pages and the printed transcript, as labels on witness attestations (chapter 03), never as a level.
8.2 The rule-set interface
A rule set is one module that exports a frozen RULES object, a classifier, an evaluator, and (optionally) a model builder for a paid artifact.
RULES metadata (MUST)
| field | type | required | meaning |
|---|---|---|---|
version | string | yes | <jurisdiction>-<program>-<year>.<n>, e.g. ny-homeschool-2026.1 |
jurisdiction | string | yes | two-letter state, or a program name for non-state lenses |
applies_to | string | yes | who the lens is for, in the statute's own terms |
primary_citation (statute_cite) | string | yes | the controlling regulation or statute, e.g. 8 NYCRR §100.10(e), 24 P.S. §13-1327.1(d) |
verified_on | ISO date | yes | the date every fact in the module was checked against a primary source |
source_url | URL | SHOULD | the primary source |
research_file | path | SHOULD | the verification trail (docs/research/...) with confidence flags |
maintained_by | string | yes (planned: not present in any module today; this draft introduces it) | the issuer or person responsible for re-verifying the module; see section 8.6 |
unit_requirements[] | {subject, units, citation, notes?, sub_requirements?[]} | units-mode lenses | every requirement carries its own citation |
total_units, cumulative_note | number, string | units-mode lenses | |
completion_doors[] | {id, title, body, citation} | SHOULD | what finishing opens, each cited |
cautions[] | {id, text, citation} | SHOULD | conflicts in primary sources are stated as cautions, never resolved into a clean claim |
Functions
| function | input | output |
|---|---|---|
classifyCourse(course) | one course row (chapter 01, section 1.4) | {bucket, sub}: the requirement bucket and optional sub-requirement id, or {bucket: null} for an unmappable row |
evaluate...(courses, opts) | the course rows, {current_date?} | {rules_version, evaluated_at, primary_citation, cumulative_note, unit_progress[{subject, required, recorded, remaining, complete, citation, contributing_courses[], sub_requirements?}], total {required, recorded, remaining, complete}, doors, cautions, unmapped_courses[]} |
build...Model(inputs) | raw family inputs plus rows | a render-agnostic model with artifact_type, rules_version, primary_citation, and the evaluation; the server re-derives from raw inputs and never trusts a client-computed evaluation |
Behavior rules (MUST)
- Pure and deterministic. No I/O, no network, no AI in this layer. Same input, same output, on client and server.
- Every requirement, door, and caution carries a citation; the evaluator reads unit counts from
RULES, never hard-codes them. - Conservative parsing: an unparsable credit counts 0; an unmappable course is surfaced in
unmapped_courses, never guessed into a core subject. - Overflow beyond a core subject's requirement flows to electives (standard transcript-evaluation practice); the rule is stated in the module.
- Vocabulary is neutral: recorded, remaining, complete, reaches, opens at. Never "behind", "chances", "qualify", "should". Doors are coverage reads, never admission predictions, match scores, or rankings.
- The output stamps
rules_versionandevaluated_atso any rendered reading can be traced to the exact rule text that produced it. - Nothing from a plugin enters a hash domain or changes a receipt. A rule set's reading is read to the learner; the operator never certifies eligibility for an institution. A competency taxonomy's claims (section 8.7) are labels on witness attestations and render on verify pages and the printed transcript, as counts of signed evidence, never as a level, a score, or a rank. (Amended 2026-09-15; before that this rule read "nothing from a plugin appears on a verifiable receipt", which the third kind narrows to the hash domains.)
8.3 The artifact-renderer interface
renderArtifactHtml(model, {preview, sample}) dispatches on model.artifact_type to a registered spec:
| spec field | type | meaning |
|---|---|---|
body(model, {preview}) | function | the document body HTML; every family-typed string passes through escapeHtml |
regReference (statute_cite) | string or null | printed in the disclaimer footer; null for letters that cite no regulation |
title(model), headerLeft(model), headerRight(model) | functions | document chrome |
Modes: the clean render (paid, printable); preview: true (watermarked with a tiled stamp and interleaved strips, blanked under print media); sample: true (marked "SAMPLE, not for filing" but printable, for public reference pages). Preview and clean output are pixel-identical apart from the marks (the family sees the filled document free; the clean print is the paid service, the only paid family surface).
Registered artifact_types today: ny_ihip, ny_quarterly, pa_portfolio, esa_expense_quarterly, expense_529_annual, year_end_summary, portfolio_packet, good_student_letter, enrollment_letter, service_hours_letter, ny_graduation_plan, credit_evaluation_packet, annual_value_report.
Model builders take raw inputs and timeline entries (chapter 01, section 1.3, the compliance metadata hours, instruction_days, subjects, state_code) and return plain objects; for example buildIhipModel({studentName, age, grade, schoolYearStart, instructors, subjectPlans, quarters}) returns {artifact_type: "ny_ihip", student, school_year, instructors, quarters[4], required_hours, subjects[{subject, plan}], recurring}.
Disclosure text (MUST appear on every artifact with a regReference)
Prepared from your own records for your review and submission. This document is not legal advice.
<regReference>is the source of truth for what your district or program requires: confirm current requirements there, and with your local district or program administrator, before you file.Regulation and program requirements used to build this document were last reviewed
<REVIEWED_AS_OF>.
REVIEWED_AS_OF (shared/reviewedAsOf.js, 2026-07-16 at the time of this draft) is one date for the regulation constants, printed on every paid artifact and shown on every state page; it is bumped by a human after re-verifying against primary sources.
8.4 Versioning rule (MUST)
versionis<jurisdiction>-<program>-<year>.<n>. Any change to a requirement, a citation, a door, a caution, or the classifier bumpsn. A new statutory year is a new module file; a shipped version is never mutated (a reading produced underny-homeschool-2026.1must stay reproducible after.2ships).verified_onis bumped only by a re-verification against primary sources, recorded inresearch_file.- Every output carries
rules_versionandevaluated_at; every artifact carriesREVIEWED_AS_OF. - Roster-like facts that change on their own cycle (a state's diploma-organization list, an ESA vendor list) are linked, never hard-coded.
8.5 Registry at the time of this draft
| module | version | jurisdiction | mode | verified_on | primary_citation |
|---|---|---|---|---|---|
ny-homeschool-2026.js | ny-homeschool-2026.1 | NY | units | (gap: no verified_on field; the date lives in the research file) | 8 NYCRR §100.10(e) |
ny-regents-2026.js | ny-regents-2026.5 | NY | diploma tracks | (gap: no verified_on field) | 8 NYCRR §100.5 |
ny-regents-family-2026.js | ny-regents-family-2026.1 | NY | units | 2026-08-10 | 8 NYCRR §100.5 |
pa-homeschool-2026.js | pa-homeschool-2026.1 | PA | units | 2026-08-08 | 24 P.S. §13-1327.1(d) |
tx-homeschool-2026.js | tx-homeschool-2026.1 | TX | presence | 2026-08-08 | TEA v. Leeper, 893 S.W.2d 432 (Tex. 1994); TEC §25.086; TEC §51.9241 (a court decision plus policy, stated as such) |
az-homeschool-2026.js | az-homeschool-2026.1 | AZ | presence | 2026-08-08 | ARS §15-802; ARS §1-701 |
fl-homeschool-2026.js | fl-homeschool-2026.1 | FL | presence | 2026-08-08 | FL Stat. §1002.41; §1009.531; §1007.271 |
ar-homeschool-2026.js | ar-homeschool-2026.1 | AR | presence | 2026-08-08 | Ark. Code §6-15-503; §6-15-504 (no diploma-recognition statute; guidance) |
college-ready-2026.js | college-ready-2026.1 | none (pattern) | pattern | 2026-08-08 | admissions patterns, NCAA core (see module) |
doors-2026.js | v2, NY day-1 to day-3 rows dated 2026-08-10 and 2026-08-11 | none (registry) | coverage read | per row | per door |
whats-next-2026.js | v1 | none (composer) | composer | draws only on cited upstream evaluations |
8.6 Presence is earned
A plugin's presence in the registry is not a product decision by the operator; it is earned by an issuer in that jurisdiction. The earning party is an issuer (a school, network, or independent counselor) operating in that jurisdiction, who also becomes the module's maintained_by and owes its verified_on re-verification cadence. A jurisdiction with no issuer has no plugin, and the Record is complete without one.
8.7 Competency taxonomies
Added 2026-09-15. Reference implementation: shared/portraitTaxonomy.js; writers api/request-attestation.js and api/issuer/declare-competency.js; reader api/verify-receipt.js; renderer frontend/src/components/PortraitSection.jsx. Vectors v25, v26.
A competency taxonomy is the attribute vocabulary a jurisdiction adopted, held as data so the record can carry witnessed evidence against it before the jurisdiction publishes its rubrics, and swapped for the jurisdiction's own words when it does. The first entry is New York's Portrait of a Graduate (six attributes, Board of Regents adoption of July 14, 2025; state rubrics pending; regulatory amendments proposed for February 2027).
The taxonomy (MUST)
PORTRAIT_TAXONOMIES is a frozen map keyed by jurisdiction. Each entry carries:
| field | type | meaning |
|---|---|---|
jurisdiction | string | the map key, two-letter state |
version | string | <adoption date>-<adopting body>, e.g. 2025-07-14-regents; a new adopted list is a new version, and a shipped version is never mutated |
name, adopted_on, adopted_by, source_line | strings | the adoption as the jurisdiction stated it; source_line prints under every rendered section |
attributes[] | {id, name, description} | the adopted attributes, verbatim names, stable ids; description is a plain one-sentence restatement of the name, marked as such by description_source, replaced by the rubric text when published |
levels | null until the jurisdiction publishes rubrics | no surface may show a level while this is null |
rubric_status | pending | flips when levels is filled |
The claim
A competency-evidence claim names one attribute and one piece of evidence: {jurisdiction, taxonomy_version, attribute_id, evidence_kind, evidence_ref, rubric_level: null}. evidence_kind is one of nine: capstone, work_sample, oral_defense, observation, project, and, for career and technical education and the trades (added 2026-09-16), hours_logged (hours on a site or in a shop, counted by the adult who supervised them), industry_credential (a credential or license earned, named as issued, with the issuing body), work_based_placement (an internship, pre-apprenticeship, apprenticeship, or job placement, witnessed by the sponsor or employer), and supervisor_observation (what a job-site or shop supervisor saw the learner do). evidence_ref is a ws_ receipt id or a short description (at most 200 characters, firewall-scanned). normalizeCompetency refuses anything the taxonomy has not defined, including an unknown kind and any non-null rubric_level.
The claim is NOT a receipt kind. It rides a witness invitation (chapter 03, section 3.2), is stored on the invitation row, and is joined to the signature that fulfilled it by fulfilled_att_id. The witness signs through the same ceremony as a course co-signature; the grade is optional for that witness (chapter 03, section 3.4). Nothing about the claim enters any hash domain (chapter 02).
Rendering (MUST)
buildPortraitSection(rows) groups signed rows by attribute, in the taxonomy's order, and returns only attributes with at least one signed row: an attribute with nothing shows nothing. Every count is a sum. No level, score, average, or rank is derived or displayed. The section carries source_line, taxonomy_version, and rubric_status, and each row carries the signer's self-declared name, role, and organization with the identity fields of chapter 03, section 3.9. The verify page (tr_ and cr_ payloads, portrait) and the printed Witness Transcript™ render the same section through the same component.
Presence (MUST)
As in section 8.6, a jurisdiction's entry is earned by an issuer in that jurisdiction, who owes its re-verification when the jurisdiction publishes. The record is complete without one: a claim from a jurisdiction with no entry is refused, never guessed into another jurisdiction's list.
8.8 What this does not prove
A plugin reading proves that the record's rows, classified by the stated rules on the stated date, cover the stated requirements to the stated extent. It does not prove that a district or program will accept the reading, that the rules have not changed since verified_on, or that a course titled to match a bucket was in fact that course. Every artifact says so in its footer; every reading carries the version and date that let a reader check. A competency taxonomy's section proves that named adults signed the listed evidence against the listed attributes; it proves nothing about how any rubric, once published, would rate that evidence, and it says so on every rendering.