Skip to content

Report theme — compliance variant — tracking #2

Description

@mmcky

Repository: QuantEcon/quantecon-theme-report.mystmd · Decisions: 2026-09-02 (D1–D8) · Design bundle: docs/design-handoff-2026-09/ at 15f6672b · 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-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
Phase 0 scaffold (#3) 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
Data contract (#4) #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
Phase 1b (#5) 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
Content migration Not started; QuantEcon/compliance-lecture-style#28, gated on Phase 1b here
Bundle manifest follow-ups #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
Decisions D1–D8 final (REVIEW §10)
Lecture theme Untouched by this plan; its cutover tracker is QuantEcon/quantecon-theme.mystmd#147

What 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 — 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 myst-cli/src/plugins.ts, resolveToAbsolute.ts compliance.mjs is a plugin shipped as a release asset beside the zip structural
Unregistered node types render as an empty span in myst-to-react and error in myst-to-tex myst-to-tex/src/index.ts (Unhandled LaTeX conversion), myst-to-react 1.3.0 DefaultComponent Portable AST only; renderers match on type + class structural
The first directive registered under a name wins; core directives register first myst-parser/src/directives.ts 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 lectures/data/ Explicit data contract before the plugin is written high
Issue and PR status on finding cards has no data source brief §5.4 placeholders findings.csv written by the pass tooling (D4) high
Static builds rewrite .html/.js/.json but not .css; asset URLs inside stylesheets must be relative QuantEcon/quantecon-theme.mystmd#138 and QuantEcon/quantecon-theme.mystmd#150 Copy scripts/relative-css-asset-urls.mjs and test with a real myst build --html medium

Work plan

Phase Issue Work item
0 #3 Scaffold the repository from the lecture theme
0 #4 Declare the compliance data contract with the ledger
1b #5 compliance.mjs: rubric-aware wrappers emitting portable nodes
2 #6 Report theme shell: fonts, tokens, top bar, sidebar, footer
3 #7 Renderers for the eight data-presentation primitives
3 #8 Card upgrades and interactions: wins, issues, finding, sortable table
3 #9 Test harness: fixture, snapshots, overflow gate, static-build smoke, preview
4 #10 First release v1.0.0 and consumer repoint

Sequencing

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.

Sources

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:

  1. 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.
  2. Get the ledger's co-sign on Phase 0: agree the data contract and add findings.csv to the pass compliance-lecture-style#29, which is open with no comments on it — nobody has answered yet, and it is worth checking whether the maintainers have actually been asked rather than only having the issue filed. Two of its five questions change what the report can truthfully say: whether the mechanical --evidence output is committed, and whether rule_titles.csv gains a checked column. 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's UPDATE.md, is what Phase 0: declare the compliance data contract with the ledger #4 is still waiting on.
  3. Phase 2 (Phase 2: report theme shell — fonts, tokens, top bar, sidebar, footer #6) runs in parallel with Phase 1b: compliance.mjs — rubric-aware wrappers emitting portable nodes #5 and with the generic directives; it shares nothing with either.
  4. 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.
  5. template.yml: use npm ci for consumer installs, or record why not #13, Port the metric-matched Source Sans 3 fallback face from the lecture theme (0842d0db) #14 and Release bundle manifest: Node floor contradicts CONTRIBUTING, and build.install ignores the shipped lockfile quantecon-theme.mystmd#162 are independent of the phase order and can land whenever.

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.

Activity

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions