When a program failure could spread to the whole institution. Proposed § 668.16(t) lets program-level failures escalate into an institution-level Title IV finding. Five independent legal frames each give the Department's chosen design a separate problem to answer.
+
+
+
+
Proposed § 668.16(t) treats sustained program-level failure as evidence of an institution-level capacity problem. The proposed mechanism — share thresholds applied across two of three measurement years — is a procedural choice the Department made on top of the program-level statute. Phase 2 of the audit walked the same proposal through five independent legal registers (statutory authority, OIRA Circular A-4 problem statement, A-4 alternatives review, A-4 uncertainty analysis, and the State Farm reasoned-decisionmaking standard). Each register raises a separate, independently sufficient question about the proposal as written.
+
+
+
+
The five frames in plain terms
+
+
Statutory authority (Loper Bright + major-questions). OBBBA § 84001 sets the program-level test. The Department points to § 498 of the Higher Education Act for the institution-level escalation pathway. Loper Bright instructs courts to read the statute themselves rather than defer; the major-questions canon adds skepticism whenever an agency claims an unusual or large new power inside a smaller statutory authority. Whether the program-level statute authorizes an institution-level Title IV consequence is a question the rule's text alone does not settle.
+
Problem statement (Circular A-4 § 1). The preamble describes the institution-level mechanism with words like "would suggest" and "could represent." A-4 § 1 asks for a demonstrated problem, not an asserted one — empirical evidence that the institution-level escalation pathway addresses a real and otherwise-unaddressed harm. The record as published does not show that demonstration.
+
Alternatives review (Circular A-4 § 6). The preamble considers and discards alternatives — disclosure-only, threshold variations, phase-in — but does not provide comparable benefit-cost tables for any of them. A-4 § 6 expects each alternative considered to be analyzed at the same depth as the chosen design.
+
Uncertainty (Circular A-4 § E). The 50% threshold and the 2-of-3-year window have no published sensitivity bounds. The published-flag-publication gap (cells whose pool-level fail flag the Department does not publish) is not analyzed. A-4 § E asks for sensitivity analysis around the choices that swing the rule's outcome.
+
Reasoned decisionmaking (Motor Vehicle Mfrs. Ass'n v. State Farm, 463 U.S. 29). State Farm's four prongs — relevant data considered, satisfactory explanation given, judgment supported by the record, alternatives addressed — form the floor for a court's arbitrary-and-capricious review. The institution-level escalation pathway design as published does not, on its face, meet all four prongs.
+
+
None of these five frames is by itself a verdict. Each is a separate legal hook for stakeholders, public commenters, or reviewing courts to test the proposed § 668.16(t) design.
+
+
+
+
How this might sound in plain language
+
If a program at this institution fails the earnings-premium test in the first measurement year, the rule's program-level consequences attach to that program (M05 / M07). The institution-level § 668.16(t) institution-level escalation pathway is a separate machinery: if a sustained share of the institution's recipients or aid dollars are in failing programs across multiple years, the Department could find the institution itself out of compliance. Whether the rule as written can support that escalation — given that the underlying earnings-premium statute is written program-by-program — is the load-bearing legal question this panel exists to surface.
+ Build a structured, citation-anchored outline you can edit into a
+ public comment on the proposed rule. The outline gives you the
+ scaffolding — the program findings, the mechanism citations, the
+ verification recipes — and leaves the substantive arguments to you.
+
+
+ ●
+ Public data only · No private or institutional data leaves your browser
+
+ The Mechanism Library walks through every mechanism the rule turns
+ on — cohort floors, benchmarks, pass / fail trigger, institution-
+ level escalation, named populations. Reading-depth toggle lets you
+ choose Brief, Standard, or Detail.
+
+ Generates a DRAFT skeleton — your institution's findings with
+ program-by-program verification recipes, mechanism citations, and
+ scaffolded topic headers you fill in. The tool gives you the
+ structure; you write the substantive arguments.
+
+ Build outline →
+
diff --git a/web/js/comment-draft.js b/web/js/comment-draft.js
new file mode 100644
index 0000000..24ad49b
--- /dev/null
+++ b/web/js/comment-draft.js
@@ -0,0 +1,259 @@
+// comment-draft.js — Persona E (cp-j0gw.5)
+// Generates a DRAFT comment outline (markdown) from an institution analysis.
+// SCAFFOLD ONLY — does not write substantive arguments. Reader fills [...] blocks.
+
+const form = document.getElementById('comment-form');
+const statusLine = document.getElementById('status-line');
+const outlineRegion = document.getElementById('outline-region');
+const outlinePre = document.getElementById('outline-pre');
+const copyBtn = document.getElementById('copy-button');
+const downloadBtn = document.getElementById('download-button');
+
+function setStatus(msg, isError = false) {
+ if (!statusLine) return;
+ statusLine.textContent = msg;
+ statusLine.classList.toggle('status-error', isError);
+}
+
+function pct(x) {
+ if (typeof x !== 'number' || Number.isNaN(x)) return '—';
+ return `${(x * 100).toFixed(2)}%`;
+}
+
+function money(x) {
+ if (typeof x !== 'number' || Number.isNaN(x)) return '—';
+ return `$${x.toLocaleString('en-US', { maximumFractionDigits: 0 })}`;
+}
+
+function buildOutline(result) {
+ const today = new Date().toISOString().split('T')[0];
+ const failing = result.programs.filter((p) => p.verdict === 'FAIL');
+ const noiseBand = result.programs.filter((p) => p.noise_band && p.noise_band.fired);
+ const notMeasured = result.programs.filter((p) => p.verdict === 'NOT MEASURED');
+
+ const lines = [];
+ lines.push(`# Public Comment Outline — DRAFT`);
+ lines.push(``);
+ lines.push(`**Subject:** Comment on the proposed STATS / Earnings-Premium rule (Federal Register 2026-07666)`);
+ lines.push(`**Submitted by:** [your name and affiliation]`);
+ lines.push(`**Date:** ${today}`);
+ lines.push(`**Institution context:** ${result.instnm} (UNITID ${result.unitid}, ${result.stabbr})`);
+ lines.push(``);
+ lines.push(`---`);
+ lines.push(``);
+ lines.push(`> **Reader notice.** This outline was generated by the public CSU Deans EP Tool`);
+ lines.push(`> (https://github.com/AJBcoding/csu-deans-ep-tool). The tool is built by`);
+ lines.push(`> educators, not attorneys or legislative analysts. Every finding below is a`);
+ lines.push(`> forward simulation on AHEAD's PPD:2026 negotiator analytic file. The first`);
+ lines.push(`> official STATS earnings-premium release is scheduled for 2027-07-01.`);
+ lines.push(`> Independently verify every citation against the primary sources before`);
+ lines.push(`> filing this comment.`);
+ lines.push(``);
+ lines.push(`---`);
+ lines.push(``);
+
+ lines.push(`## 1. Findings at this institution`);
+ lines.push(``);
+ if (failing.length > 0) {
+ lines.push(`### Programs failing the EP test`);
+ lines.push(``);
+ for (const p of failing) {
+ lines.push(`- **${p.cip4_title}** (CIP ${p.cip4} · ${p.credlev}) — verdict: **FAIL** at ${pct(p.ep_gap_pct)} (cohort n=${p.cohort_count ?? '—'}; median earnings ${money(p.median_earn_p4)} vs benchmark ${money(p.benchmark)} via ${p.benchmark_route}).`);
+ }
+ lines.push(``);
+ } else {
+ lines.push(`No programs at this institution surface a FAIL verdict in the simulation.`);
+ lines.push(``);
+ }
+
+ if (noiseBand.length > 0) {
+ lines.push(`### Programs in the noise band (verdict could read either way under privacy noise)`);
+ lines.push(``);
+ for (const p of noiseBand) {
+ lines.push(`- **${p.cip4_title}** (CIP ${p.cip4} · ${p.credlev}) — current verdict ${p.verdict} at ${pct(p.ep_gap_pct)}; gap is within ±15% of zero.`);
+ }
+ lines.push(``);
+ }
+
+ if (notMeasured.length > 0) {
+ lines.push(`### Programs not measured (cohort suppression, invisibility, or out-of-scope)`);
+ lines.push(``);
+ for (const p of notMeasured) {
+ lines.push(`- **${p.cip4_title || '(unknown)'}** (CIP ${p.cip4} · ${p.credlev}) — reason: ${p.not_measured_reason ?? 'unspecified'}.`);
+ }
+ lines.push(``);
+ }
+
+ lines.push(`---`);
+ lines.push(``);
+ lines.push(`## 2. Mechanism context (citations to the proposed rule)`);
+ lines.push(``);
+ if (Array.isArray(result.panels)) {
+ for (const panel of result.panels) {
+ lines.push(`- **${panel.id}** — ${panel.header}`);
+ }
+ }
+ lines.push(``);
+ lines.push(`Trigger reason for each: see Mechanism Library at /learn/. The full text of each panel — including the primary-source citations — appears in the tool's content/mdocs/ directory.`);
+ lines.push(``);
+ lines.push(`---`);
+ lines.push(``);
+
+ lines.push(`## 3. Suggested topics for substantive comment (you fill in)`);
+ lines.push(``);
+ lines.push(`The tool does not write substantive comment text. The headers below are`);
+ lines.push(`scaffolds for the topics this institution's findings tend to surface.`);
+ lines.push(`Each is a placeholder — write your own substantive position.`);
+ lines.push(``);
+ lines.push(`### 3.1 What this institution loses if the rule takes effect as written`);
+ lines.push(``);
+ lines.push(`[Describe the program-level and student-level impact in your own words.`);
+ lines.push(`Reference the failing programs above; explain who they serve, what they`);
+ lines.push(`teach, and why earnings-premium is or is not the right outcome metric for`);
+ lines.push(`those programs at this institution.]`);
+ lines.push(``);
+
+ if (failing.length > 0) {
+ lines.push(`### 3.2 The institution-level § 668.16(t) escalation pathway`);
+ lines.push(``);
+ lines.push(`[The Mechanism Library panel M18 walks through the five legal frames the`);
+ lines.push(`Department's design must answer (Loper Bright + major-questions, OIRA`);
+ lines.push(`Circular A-4 § 1, § 6, § E, and Motor Vehicle Mfrs. v. State Farm). If`);
+ lines.push(`you have a legal position on the institution-level escalation design, this`);
+ lines.push(`is where to put it. The tool does not take a legal position; it surfaces`);
+ lines.push(`the questions for you to answer or to ask counsel about.]`);
+ lines.push(``);
+ }
+
+ lines.push(`### 3.3 Cohort-floor methodology (cp-wssr finding)`);
+ lines.push(``);
+ lines.push(`[The OBBBA § 84001(c)(2)(A) statutory floor is 30 graduates; AHEAD's`);
+ lines.push(`single-window count_wne_p4 may show fewer at this institution. Mechanism`);
+ lines.push(`Library panel M01 walks through the AHEAD-published-flag override the tool`);
+ lines.push(`applies. If your institution has cells in the 16-30 single-window range`);
+ lines.push(`with PPD-published flags, you may want to address how the cohort-floor`);
+ lines.push(`mismatch interacts with appeal scope under proposed § 668.603.]`);
+ lines.push(``);
+
+ lines.push(`### 3.4 Disparate impact on named populations`);
+ lines.push(``);
+ lines.push(`[Mechanism Library panel M14 covers RIA Table 3.19 named-population`);
+ lines.push(`elevation. If this institution serves named populations (HBCU, MSI, HSI,`);
+ lines.push(`AANAPISI, or programs in CIP 50.05/50.07/50.09/51.15) and the rule's`);
+ lines.push(`elevation factor differs from the prose summary in the RIA, this is where`);
+ lines.push(`to address it.]`);
+ lines.push(``);
+
+ lines.push(`---`);
+ lines.push(``);
+ lines.push(`## 4. Verification recipes — how each number above can be reproduced`);
+ lines.push(``);
+ if (failing.length > 0) {
+ lines.push(`Each failing program above can be reproduced WITHOUT this tool, using only`);
+ lines.push(`the AHEAD codebook + the Department's published file. Recipes:`);
+ lines.push(``);
+ for (const p of failing) {
+ const r = p.verification_recipe;
+ if (!r) continue;
+ lines.push(`### ${p.cip4_title} (CIP ${p.cip4} · ${p.credlev})`);
+ lines.push(``);
+ lines.push(`- **Source data:** ${r.source_data}`);
+ lines.push(`- **Source grain:** ${r.source_grain}`);
+ lines.push(`- **Engine reference:** \`${r.engine_reference}\``);
+ lines.push(`- **Source fields:** ${r.source_fields.join('; ')}`);
+ lines.push(`- **Steps:**`);
+ for (const step of r.steps) {
+ lines.push(` 1. ${step}`);
+ }
+ lines.push(``);
+ }
+ }
+
+ lines.push(`---`);
+ lines.push(``);
+ lines.push(`## 5. References`);
+ lines.push(``);
+ lines.push(`### Primary sources cited above`);
+ lines.push(``);
+ lines.push(`- AHEAD PPD:2026 — Program Performance Data file 112908 (Department of Education / NCES)`);
+ lines.push(`- IPEDS Completions Survey (NCES)`);
+ lines.push(`- OBBBA — Public Law 119-21, § 84001 (program-level EP test); § 81001 (graduate loan caps)`);
+ lines.push(`- Higher Education Act § 498 (administrative-capability authority)`);
+ lines.push(`- STATS NPRM — Federal Register 2026-07666 (proposed § 668.2(b), § 668.16(t), § 668.402(c)(3), § 668.403(d)(1), § 668.404(d), § 668.43(d)(1), § 668.603; RIA Tables 3.1, 3.9, 3.19)`);
+ lines.push(`- OIRA Circular A-4 (2003) — § 1 problem statement; § 6 alternatives; § E uncertainty`);
+ lines.push(`- *Loper Bright Enterprises v. Raimondo*, 603 U.S. ___ (2024)`);
+ lines.push(`- *Motor Vehicle Mfrs. Ass'n v. State Farm Mut. Auto. Ins. Co.*, 463 U.S. 29 (1983)`);
+ lines.push(``);
+ lines.push(`### Tool reference`);
+ lines.push(``);
+ lines.push(`- This outline generated by the CSU Deans EP Tool — https://github.com/AJBcoding/csu-deans-ep-tool (MIT license).`);
+ lines.push(`- Public Sources page: /sources.html.`);
+ lines.push(`- Mechanism Library: /learn/.`);
+ lines.push(``);
+ lines.push(`---`);
+ lines.push(``);
+ lines.push(`**End of DRAFT outline.** Edit substantively before filing. Verify every citation against the primary source. The tool is not a legal product, not legal advice, and not a filed position of any institution.`);
+ lines.push(``);
+
+ return lines.join('\n');
+}
+
+async function fetchAnalysis(unitid) {
+ const res = await fetch(`/api/v1/analysis/${unitid}`);
+ if (!res.ok) {
+ throw new Error(`API ${res.status}`);
+ }
+ return await res.json();
+}
+
+let lastOutline = '';
+let lastUnitid = '';
+
+if (form && outlineRegion && outlinePre) {
+ form.addEventListener('submit', async (ev) => {
+ ev.preventDefault();
+ const data = new FormData(form);
+ const unitid = String(data.get('unitid') ?? '').trim();
+ if (!/^[0-9]+$/.test(unitid)) {
+ setStatus('UNITID must be all digits.', true);
+ return;
+ }
+ setStatus(`Fetching analysis for UNITID ${unitid}…`);
+ outlineRegion.hidden = true;
+ try {
+ const result = await fetchAnalysis(unitid);
+ lastOutline = buildOutline(result);
+ lastUnitid = unitid;
+ outlinePre.textContent = lastOutline;
+ outlineRegion.hidden = false;
+ setStatus(`Outline generated for ${result.instnm} (${result.unitid}). Edit and verify before filing.`);
+ } catch (err) {
+ setStatus(`Could not fetch analysis: ${String(err)}`, true);
+ }
+ });
+}
+
+if (copyBtn) {
+ copyBtn.addEventListener('click', async () => {
+ if (!lastOutline) return;
+ try {
+ await navigator.clipboard.writeText(lastOutline);
+ setStatus('Outline copied to clipboard.');
+ } catch (e) {
+ setStatus('Copy failed; select-all the text below instead.', true);
+ }
+ });
+}
+
+if (downloadBtn) {
+ downloadBtn.addEventListener('click', () => {
+ if (!lastOutline) return;
+ const blob = new Blob([lastOutline], { type: 'text/markdown' });
+ const url = URL.createObjectURL(blob);
+ const a = document.createElement('a');
+ a.href = url;
+ a.download = `comment-outline-${lastUnitid}.md`;
+ a.click();
+ URL.revokeObjectURL(url);
+ });
+}
diff --git a/web/js/learn.js b/web/js/learn.js
new file mode 100644
index 0000000..836f9d7
--- /dev/null
+++ b/web/js/learn.js
@@ -0,0 +1,79 @@
+// learn.js — Mechanism Library page (cp-j0gw.9 + .10)
+// Loads each M-doc HTML inline and wires the reading-depth toggle.
+
+const PANEL_ORDER = [
+ 'M01', 'M03', 'M04', 'M07',
+ 'M05', 'M06', 'M18',
+ 'M12', 'M13', 'M14',
+ 'M02', 'M08', 'M09', 'M10', 'M11', 'M15', 'M17',
+];
+
+const DEPTH_KEY = 'csu-ep-tool:reading-depth';
+const VALID_DEPTHS = new Set(['brief', 'standard', 'detail']);
+
+async function loadPanel(id) {
+ // In dev-server: /content/mdocs/* served from /content/mdocs/*.
+ // In dist-pages build: content/ is copied alongside web/ outputs.
+ const res = await fetch(`./content/mdocs/${id}.html`);
+ if (!res.ok) {
+ throw new Error(`Failed to load ${id}: HTTP ${res.status}`);
+ }
+ return await res.text();
+}
+
+async function renderPanels() {
+ const region = document.getElementById('panel-region');
+ if (!region) return;
+ region.innerHTML = '';
+ const fragments = await Promise.all(
+ PANEL_ORDER.map(async (id) => {
+ try {
+ const html = await loadPanel(id);
+ return `
+ Plain-language walks through every mechanism the rule turns on. Read
+ these before running a check, or alongside one. Each panel cites the
+ primary source it rests on.
+
+
+ ●
+ Public data only · No private or institutional data leaves your browser
+