You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
This is a long-lived tracker: the single source of truth for the report theme's first variant, revised in place against live state, resumed and updated but never session-closed. Work items are the native sub-issues below; body checkboxes are not used.
Background
QuantEcon/compliance-lecture-style is a standing conformance ledger (QEP-3 compliance-* type) published today as a Jupyter Book 1 site with the Sphinx quantecon-book-theme: 348 per-lecture reports, 5 series pages, charts drawn by matplotlib code cells, and every table spliced into the markdown by tools/qestyle_report.py from lectures/data/*.csv (UPDATE.md § Step 5 at a92f911b). A design handover (brief) specifies a MyST report theme for it: structured report blocks become CSV-backed directives rendered as rich components, so the visuals cannot drift from the measured data, and the site moves onto the mystmd stack the lecture series are migrating to.
The review of that brief settled eight decisions with the maintainer on 2026-09-02 (REVIEW §10). The ones that shape this repository: it is a self-contained sibling of the lecture theme with the lecture scaffolding copied and no shared package (D1); it releases on plain vX.Y.Z tags with two assets, quantecon-theme-report.zip and compliance.mjs (D2); every directive emits portable MyST AST with no custom node types, upgraded by this theme's renderers (D3); the generic data-presentation directives live in quantecon-plugins.mystmd and this repo implements their node contract (D7); the first version is light-only (D5).
Where we stand (verified 2026-09-10 17:25 AEST)
Area
State
Repository
main @ 50dc734. Labels: QEP-2 core set plus refactor; delete-branch-on-merge on
Code-complete 2026-09-03: #12 squash-merged as 50dc734. Remix runtime, Tailwind, four green workflows, Playwright rendering and first-paint guards, the release-bundle template, unit tests guarding version stamping. #3 stays open for the two criteria that are not code: the release rehearsal and FAMILY.md in the lecture theme
#15 merged 2026-09-10 as 70db91a: docs/compliance-data.md, measured against the ledger at the 2026-08 pass rather than read off the brief. #4 stays open, and deliberately: two of its four acceptance criteria are ledger-side and unmet — the cross-link from the ledger's UPDATE.md (no reference exists there yet) and the maintainer's acknowledgement on QuantEcon/compliance-lecture-style#29, which is open with no comments on it. The two that are this repository's half are met
Not started, and now the front of the plan: the syntax sheet is settled, merged and the directive forms are specified. It does not wait on the ledger's co-sign, though two of the co-sign's five questions change what parts of it can truthfully say
Generic directives
QuantEcon/quantecon-plugins.mystmd#2. Both merged 2026-09-10: the contract audit and the two-container-form specification (QuantEcon/quantecon-plugins.mystmd#22, 12f3a9f) and the release pipeline (QuantEcon/quantecon-plugins.mystmd#21, 3beef97). v0.0.1 is released, so there is now a real release URL to pin — though the bundle registers no directives yet, so nothing here can use it in anger until QuantEcon/quantecon-plugins.mystmd#5 and #6 land, which lead there next. One thing to carry into Phase 2 and the deploy work: QuantEcon/mystmd#101 — a project.plugins URL that 404s does not fail myst build --html --strict, so a stale or mistyped pin publishes a green site with every plugin-provided component silently absent
#13 (npm ci for consumer installs) and QuantEcon/quantecon-theme.mystmd#162 — the same pair in the lecture theme this repo was copied from. Independent of the phase order
Three findings from #15 change what Phase 1b builds, and are recorded here because they are the sort of thing a plan loses.
The issue cards' prose splits in two, and only half of it exists. The brief says issue lines and example text live only in the generated markdown. That is right about the CSVs and wrong about the ledger. For the reviewer half, reviews/<series>/<lecture>.json — 348 files — carries judgment[{rule, count, lines, detail}] plus strengths, actions and a commit-and-blob provenance stamp, and tools/qestyle_draft.py drops lines and detail on the way to judgment.csv. So the plugin reads reviews/, not judgment.csv, and no ledger tooling changes for that half. For the mechanical half those lines and examples are produced live at draft time and persisted nowhere, so either the --evidence output is committed or mechanical cards carry a title and a count and no example. That is the one open question blocking a designed region.
The sentinels are not what the brief says. An empty cell never means "not in scope". N/A (263 occurrences, five columns) is "not applicable to this lecture"; out-of-scope (348, the jax column only) is "never in the audit's remit", and spec.md says the two are distinct; an empty cell (5 occurrences, all in aggregates) is a mean over zero in-scope values and must never be coerced to 0, since 0 is the most severe score on the scale. Because the datavis contract has one vocabulary for a missing value, the distinction goes in a second property rather than a second spelling.
The key is (series, lecture). 348 rows carry 281 distinct stems, and 57 stems appear in more than one series across 124 rows, so a join on lecture alone silently merges lectures from different series. Two series names contain a dot, so a series value must not be split on ..
Findings that shape the work
Finding
Evidence
Consequence
Severity
A site template cannot contribute directives; plugins load only from project.plugins as a local .mjs path or a URL
Each family registers once; plain names with an alias fallback
medium
Sidebar series list and footer stats are CSV-driven chrome the theme cannot compute
brief §5.0; manifest exposes only title/slug/level/date/thumbnail/tags
site.parts (series_nav, report_meta) carry the data
structural
scores.csv uses N/A and out-of-scope sentinels and a jax column the brief omits; rule_reach_history.csv has six columns not three; per-series reach is series_rule_reach.csv
Phase 0 gates everything: the scaffold gives every later PR a CI to land on, and the data contract is what the compliance plugin reads. Phases 1b and 2 are independent of each other and of the generic directives in QuantEcon/quantecon-plugins.mystmd#2, so all three run in parallel. Phase 3 needs all three, because the renderers implement the plugins repo's node contract and the shell hosts them. The Phase 1b exit is the moment the content repo can start its migration project (QuantEcon/compliance-lecture-style#28): with both plugins emitting portable output, the ledger builds on the default or lecture theme with plain tables before any renderer exists. Phase 4 needs Phase 3 and the compliance repo's migration to be ready to repoint.
What does not need to change
The lecture theme: no file in quantecon-theme.mystmd changes for this plan beyond a small FAMILY.md conventions document and the separately tracked QuantEcon/quantecon-plugins.mystmd#11. The ledger's prose: narrative between directives stays ordinary MyST markdown, and qestyle_check.py keeps its role for hand-written claims. The consumption model: a compliance site pins a theme zip and plugin URLs in myst.yml, exactly as lecture sites do.
compliance-lecture-style at a92f911b: data files, tooling, runbook
Next session — resume here
The data contract is merged — #15 landed 2026-09-10 as 70db91a. Phase 1b (#5) is the front of the plan.
In order:
Phase 1b: compliance.mjs — rubric-aware wrappers emitting portable nodes #5, Phase 1b. The syntax sheet is settled and on main: the card kit keeps its container-and-item form as a stated exception to the datavis family rule, and every container offers two forms, both supported — nested in one fence, or gated as {qe-…-start} … {qe-…-end}. Either carries a code-cell, verified with a real kernel at any nesting depth, so the choice is about editing rather than execution. Reach for the gated form for executable content, following qe-admon-001, and for any long or often-edited card set: a mis-nested container exits 0 and swallows the rest of the page into a code node, while an unclosed gate exits 1. Keep the nested form for prose cards — it is the only one in which the container can reject a bad item with a line number. Both are specified in the plugins repository's CONTRACT.md, on main since 12f3a9f. Phase 1b's exit is what unblocks Migrate the ledger to mystmd with the report theme — tracking compliance-lecture-style#28.
Phase 0: scaffold the repository from the lecture theme #3's tail — the release rehearsal, and FAMILY.md in the lecture theme. The stated reason for holding FAMILY.md has lapsed, and it must state the plugin-distribution convention from QuantEcon/workspace-themes#12.
Two engine facts to carry into Phase 2 and Phase 3, both verified against mystmd 1.10.1 and recorded in the plugins repository's CONTRACT.md or QuantEcon/mystmd#101. myst build --md writes no export file at all for a page carrying a div-rooted node, logging Unsupported node type: div and exiting 0 under --strict; core {div} fails identically, so it is an engine gap rather than something this theme caused. Site and LaTeX builds are unaffected, which is what the compliance ledger needs — but a test harness that asserts on an exported .md will assert on nothing. And a project.plugins URL that cannot be fetched does not fail --strict either, so a stale or mistyped pin publishes a green site with every plugin-provided component silently absent; this repository is planned to pin three plugin URLs plus a theme zip, so its deploy gate needs a positive "the plugin loaded" assertion rather than the exit code.
Re-verify the table above before working the plan; facts are only true as of the stamp.
Repository: QuantEcon/quantecon-theme-report.mystmd · Decisions: 2026-09-02 (D1–D8) · Design bundle:
docs/design-handoff-2026-09/at15f6672b· Sibling trackers: QuantEcon/quantecon-plugins.mystmd#2 (generic directives), QuantEcon/compliance-lecture-style#28 (content migration)This is a long-lived tracker: the single source of truth for the report theme's first variant, revised in place against live state, resumed and updated but never session-closed. Work items are the native sub-issues below; body checkboxes are not used.
Background
QuantEcon/compliance-lecture-styleis a standing conformance ledger (QEP-3compliance-*type) published today as a Jupyter Book 1 site with the Sphinxquantecon-book-theme: 348 per-lecture reports, 5 series pages, charts drawn by matplotlib code cells, and every table spliced into the markdown bytools/qestyle_report.pyfromlectures/data/*.csv(UPDATE.md § Step 5 ata92f911b). A design handover (brief) specifies a MyST report theme for it: structured report blocks become CSV-backed directives rendered as rich components, so the visuals cannot drift from the measured data, and the site moves onto the mystmd stack the lecture series are migrating to.The review of that brief settled eight decisions with the maintainer on 2026-09-02 (REVIEW §10). The ones that shape this repository: it is a self-contained sibling of the lecture theme with the lecture scaffolding copied and no shared package (D1); it releases on plain
vX.Y.Ztags with two assets,quantecon-theme-report.zipandcompliance.mjs(D2); every directive emits portable MyST AST with no custom node types, upgraded by this theme's renderers (D3); the generic data-presentation directives live inquantecon-plugins.mystmdand this repo implements their node contract (D7); the first version is light-only (D5).Where we stand (verified 2026-09-10 17:25 AEST)
main@50dc734. Labels: QEP-2 core set plusrefactor; delete-branch-on-merge on50dc734. Remix runtime, Tailwind, four green workflows, Playwright rendering and first-paint guards, the release-bundle template, unit tests guarding version stamping. #3 stays open for the two criteria that are not code: the release rehearsal andFAMILY.mdin the lecture theme70db91a:docs/compliance-data.md, measured against the ledger at the 2026-08 pass rather than read off the brief. #4 stays open, and deliberately: two of its four acceptance criteria are ledger-side and unmet — the cross-link from the ledger'sUPDATE.md(no reference exists there yet) and the maintainer's acknowledgement on QuantEcon/compliance-lecture-style#29, which is open with no comments on it. The two that are this repository's half are met12f3a9f) and the release pipeline (QuantEcon/quantecon-plugins.mystmd#21,3beef97).v0.0.1is released, so there is now a real release URL to pin — though the bundle registers no directives yet, so nothing here can use it in anger until QuantEcon/quantecon-plugins.mystmd#5 and #6 land, which lead there next. One thing to carry into Phase 2 and the deploy work: QuantEcon/mystmd#101 — aproject.pluginsURL that 404s does not failmyst build --html --strict, so a stale or mistyped pin publishes a green site with every plugin-provided component silently absentnpm cifor consumer installs) and QuantEcon/quantecon-theme.mystmd#162 — the same pair in the lecture theme this repo was copied from. Independent of the phase orderWhat the data contract found
Three findings from #15 change what Phase 1b builds, and are recorded here because they are the sort of thing a plan loses.
The issue cards' prose splits in two, and only half of it exists. The brief says issue lines and example text live only in the generated markdown. That is right about the CSVs and wrong about the ledger. For the reviewer half,
reviews/<series>/<lecture>.json— 348 files — carriesjudgment[{rule, count, lines, detail}]plus strengths, actions and a commit-and-blob provenance stamp, andtools/qestyle_draft.pydropslinesanddetailon the way tojudgment.csv. So the plugin readsreviews/, notjudgment.csv, and no ledger tooling changes for that half. For the mechanical half those lines and examples are produced live at draft time and persisted nowhere, so either the--evidenceoutput is committed or mechanical cards carry a title and a count and no example. That is the one open question blocking a designed region.The sentinels are not what the brief says. An empty cell never means "not in scope".
N/A(263 occurrences, five columns) is "not applicable to this lecture";out-of-scope(348, thejaxcolumn only) is "never in the audit's remit", andspec.mdsays the two are distinct; an empty cell (5 occurrences, all in aggregates) is a mean over zero in-scope values and must never be coerced to0, since0is the most severe score on the scale. Because the datavis contract has one vocabulary for a missing value, the distinction goes in a second property rather than a second spelling.The key is
(series, lecture). 348 rows carry 281 distinct stems, and 57 stems appear in more than one series across 124 rows, so a join onlecturealone silently merges lectures from different series. Two series names contain a dot, so a series value must not be split on..Findings that shape the work
project.pluginsas a local.mjspath or a URLmyst-cli/src/plugins.ts,resolveToAbsolute.tscompliance.mjsis a plugin shipped as a release asset beside the zipmyst-to-reactand error inmyst-to-texmyst-to-tex/src/index.ts(Unhandled LaTeX conversion),myst-to-react1.3.0DefaultComponentmyst-parser/src/directives.tssite.parts(series_nav,report_meta) carry the datascores.csvusesN/Aandout-of-scopesentinels and ajaxcolumn the brief omits;rule_reach_history.csvhas six columns not three; per-series reach isseries_rule_reach.csvlectures/data/findings.csvwritten by the pass tooling (D4).html/.js/.jsonbut not.css; asset URLs inside stylesheets must be relativescripts/relative-css-asset-urls.mjsand test with a realmyst build --htmlWork plan
compliance.mjs: rubric-aware wrappers emitting portable nodesv1.0.0and consumer repointSequencing
Phase 0 gates everything: the scaffold gives every later PR a CI to land on, and the data contract is what the compliance plugin reads. Phases 1b and 2 are independent of each other and of the generic directives in QuantEcon/quantecon-plugins.mystmd#2, so all three run in parallel. Phase 3 needs all three, because the renderers implement the plugins repo's node contract and the shell hosts them. The Phase 1b exit is the moment the content repo can start its migration project (QuantEcon/compliance-lecture-style#28): with both plugins emitting portable output, the ledger builds on the default or lecture theme with plain tables before any renderer exists. Phase 4 needs Phase 3 and the compliance repo's migration to be ready to repoint.
What does not need to change
The lecture theme: no file in
quantecon-theme.mystmdchanges for this plan beyond a smallFAMILY.mdconventions document and the separately tracked QuantEcon/quantecon-plugins.mystmd#11. The ledger's prose: narrative between directives stays ordinary MyST markdown, andqestyle_check.pykeeps its role for hand-written claims. The consumption model: a compliance site pins a theme zip and plugin URLs inmyst.yml, exactly as lecture sites do.Sources
15f6672b: brief, review and decisions, plan47e37ed8(v2.3.1 plus fix: rewrite asset URLs in route stylesheets, not just those in _assets/ quantecon-theme.mystmd#151): the scaffold to copy12a8b26b(v1.10.1, qe-v10): plugin loading, directive registration, strict modea92f911b: data files, tooling, runbookNext session — resume here
The data contract is merged — #15 landed 2026-09-10 as
70db91a. Phase 1b (#5) is the front of the plan.In order:
main: the card kit keeps its container-and-item form as a stated exception to the datavis family rule, and every container offers two forms, both supported — nested in one fence, or gated as{qe-…-start}…{qe-…-end}. Either carries acode-cell, verified with a real kernel at any nesting depth, so the choice is about editing rather than execution. Reach for the gated form for executable content, followingqe-admon-001, and for any long or often-edited card set: a mis-nested container exits 0 and swallows the rest of the page into acodenode, while an unclosed gate exits 1. Keep the nested form for prose cards — it is the only one in which the container can reject a bad item with a line number. Both are specified in the plugins repository'sCONTRACT.md, onmainsince12f3a9f. Phase 1b's exit is what unblocks Migrate the ledger to mystmd with the report theme — tracking compliance-lecture-style#28.--evidenceoutput is committed, and whetherrule_titles.csvgains acheckedcolumn. Phase 1b: compliance.mjs — rubric-aware wrappers emitting portable nodes #5 can begin without them, but the regions that depend on them cannot be finished. That co-sign, plus a cross-link from the ledger'sUPDATE.md, is what Phase 0: declare the compliance data contract with the ledger #4 is still waiting on.FAMILY.mdin the lecture theme. The stated reason for holdingFAMILY.mdhas lapsed, and it must state the plugin-distribution convention from QuantEcon/workspace-themes#12.Two engine facts to carry into Phase 2 and Phase 3, both verified against mystmd 1.10.1 and recorded in the plugins repository's
CONTRACT.mdor QuantEcon/mystmd#101.myst build --mdwrites no export file at all for a page carrying adiv-rooted node, loggingUnsupported node type: divand exiting 0 under--strict; core{div}fails identically, so it is an engine gap rather than something this theme caused. Site and LaTeX builds are unaffected, which is what the compliance ledger needs — but a test harness that asserts on an exported.mdwill assert on nothing. And aproject.pluginsURL that cannot be fetched does not fail--stricteither, so a stale or mistyped pin publishes a green site with every plugin-provided component silently absent; this repository is planned to pin three plugin URLs plus a theme zip, so its deploy gate needs a positive "the plugin loaded" assertion rather than the exit code.Re-verify the table above before working the plan; facts are only true as of the stamp.