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.
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.
Two 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.
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 appears on a verifiable receipt. Doors are read to the learner; the operator never certifies eligibility for an institution.
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 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.