MySTRA becomes a stock-MyST plugin for ASTRA analyses#5
Conversation
Invert the architecture: instead of generating a whole document from astra.yaml and serving it through a bespoke content server, MySTRA is now a single MyST plugin (directives + roles + transforms) that imports/cites ASTRA components into an author-written Markdown report and runs on the stock `myst` CLI + themes. Net -6k lines. Removed (generate-everything era): - src/server/ (Express content server + ws + watcher), src/cli.ts, src/theme/launcher.ts, src/transform/index.ts (whole-page orchestration), src/types/content-server.ts, src/utils/hash.ts - DOI/paper subsystem (src/doi/, src/papers/) — citations now lean on MyST - unused render-* helpers; old server/page-shape tests Added / reshaped: - the plugin is the package entry: src/index.ts (default export = plugin) - recognition markers (astra-* classes) + per-page resolved data store (hidden div.astra-store) for rich themes - deterministic, lazy result-artifact resolution (lightcone path convention) — no filesystem scanning - tests/plugin-emission.test.ts Lean on @astra-spec/sdk: - data-model types imported by their SDK names (no local types/ module) - runtime reuse: loadYaml, resolveAnalysisTree, isConditionMet (js-yaml dropped) Flattened to src/index.ts + src/loader.ts + src/transform/*. Docs (README, SPEC) rewritten; rationale in STRATEGY-A-REFACTOR.md. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…r branch The module isn't about the `narrative:` field (Strategy A ignores it — the author writes that prose in the Markdown page). It's the engine for the Markdown embedded in components (rationale, claim, notes, descriptions, captions) + the ASTRA anchor resolver. Renamed to `prose.ts` to match, and repointed every importer. Also removed the `#narrative.<section>` case in resolveAnchorPath: it minted `narrative-<section>` identifiers that have no carrier and otherwise fell through to the plain-link default. Dropped its two now-obsolete tests. The `narrative.summary` blurb on sub-analysis cards is kept. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…ng scope) Captures the deferred work: SDK-based input validation, MyST-native citations/bibliography, astra.yaml live-reload, and deepening the page-scope derivation beyond one level. Each with problem / approach / code refs / risk. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
The prototype no longer wires a custom.css (it demonstrates the plugin-only baseline), so README/SPEC/plan no longer describe it as the "seed/preview" stylesheet; the rich styling is the lightcone-astra theme's job. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…lity Append an appendix: the engine-resolves/theme-renders model; citations as a key→references.cite.data join (cite.tsx) vs cross-references as an identifier→mdast-node resolve (crossReference.tsx); that a theme can add a cite-like mechanism via mergeRenderers + a context provider (in bounds, since it renders baked output). Corrects §2 — DOIs already resolve to citations natively — and records the insight-preview plan (hidden same-page xref targets for the baseline; a store-driven renderer for lightcone-astra). Sources cited. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
…tions Lead with the concrete next piece (hidden same-page crossReference targets for prior_insights, so the option-tab hovers keep working without the 32-block "Analysis record" appendix in index.md). Cross-references the Appendix for the display:none-works-because-mdast-not-DOM mechanism. Drop §2 citations entirely: the appendix already shows DOIs auto-resolve to cite nodes + references.cite in book-theme, so the residue (a reference-list directive, offline behaviour) is too narrow to live as its own follow-up — now a single sentence inside the citation explanation. Trim the rest. Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
Lead with the user story (publications on top of ASTRA analyses) and a motivating example; present the published-package workflow (npm install @astra-spec/mystra, reference by name in myst.yml) instead of the local prototype shim. Demote internals to theme-author/contributor sections. Rename package to @astra-spec/mystra; reset version to 0.0.1. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Replace the Apache-2.0 LICENSE with astra-spec's BSD 3-Clause text; fix the package.json license field (MIT) and README footer to match. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The package-lock root entry still carried the old name (mystra), version (0.2.0), and license (MIT). Align it with package.json. Third-party dependency license fields are unchanged. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@claude please review this PR carefully |
The collapsed "ASTRA provenance" details emitted after each figure/table duplicated the rich theme's ProvenanceDrawer (every output showed two provenance UIs). Provenance rendering is the theme's job — it reads the resolved store; plain book-theme simply shows the figure. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…ons_transitive)
Outputs' declared inputs[]/decisions[] are direct edges only; the useful
question for a reader is what actually affects a result. A new tracer
walks the provenance chain at store-build time — through dotted output
refs, input cross-links (incl. sibling scopes via ancestor climbing),
same-scope chaining, output `from:` aliases, and `../` decision aliases,
narrowing the universe per descent — and flattens it onto each
SerializedOutput:
inputs_root analysis-level source files only
decisions_transitive every decision on the chain, with the selected
option label and a root-relative `via` scope when
not the page's own
Designed via the theme's design-mirror Proposals page.
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Code Review — PR #5: "MySTRA becomes a stock-MyST plugin for ASTRA analyses"I reviewed the diff plus the resulting working tree, built it, and ran the test suite. Build is clean. The test suite is not — and that's the headline finding. OverviewA large, well-executed architectural pivot: MySTRA stops being a generate-everything Express content server and becomes a single MyST plugin (directives + roles + transforms) that runs on the stock 🔴 Blocking: the new test surface can't run in a clean checkoutThe headline new file Result on a fresh clone of this branch: Every This directly contradicts the PR's test plan checkbox Options, roughly in order of preference:
As it stands, the core behavior of the new plugin is effectively untested for anyone but the author. Code quality & correctnessGenerally high. Specific notes:
Smaller things
VerdictThe architecture, the deletions, and the code itself are strong — the design is approvable. But the principal test file is red on a clean checkout while the test plan claims otherwise. Please commit a fixture (or gate the suite) and ideally add CI before merge. Everything else above is non-blocking polish. 🤖 Generated with Claude Code |
Update — blocking issue addressedResolved the test-suite problem by removing the
Tradeoff: this drops emission/role/value/resolved-store coverage — exactly the surface this refactor adds. Follow-up: a self-contained emission suite that builds a tiny 🤖 Generated with Claude Code |
The plugin-emission suite drove the plugin against an uncommitted, gitignored `prototype/` project, so it failed 22/64 in any clean checkout. Remove the prototype coupling rather than vendor the fixture: - drop `prototype/`/`dev/` from .gitignore - delete tests/plugin-emission.test.ts - add minimal CI (build + test on Node 20) Remaining suites (loader-validation, prose) are self-contained and green; emission coverage to be restored via a temp-dir fixture suite. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
|
@claude Can you redo a review of the current state of the project? |
|
Claude finished @EiffL's task in 3m 39s —— View job Code Review — PR #5 (current state)
|
Code fixes from the PR #5 re-review: - provenance: climb one scope per `../` in decision-alias resolution (greedy strip collapsed `../../x` to a single climb, resolving it in the wrong scope) - cache: bust the source cache when the active universe file changes, not just astra.yaml (editing a universe changes decision selections); expose universeFilePath from the loader so both agree - render-evidence: drop the dead `outputId` param from the resultUrl option type + call site (factory only ever passes absPath) - resolved-store: fix stale doc reference (astra-plugin.ts -> index.ts) Tests: - add tests/plugin-core.test.ts: a self-contained temp-dir fixture (own astra.yaml/universe/results) driving every directive, the cite and value roles, the resolved store, transitive provenance with universe narrowing, and the mtime cache. No prototype dependency. - 77 tests pass (was 38); the `../` traversal test is a verified regression guard for the provenance fix. Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Addressed the re-review —
|

Summary
Reworks MySTRA from a generate-everything content server into a single MyST plugin. Instead of generating and serving the whole document, an author writes a normal MyST Markdown report and imports/cites ASTRA components by reference; the plugin reads
astra.yamlat build time and emits standard MyST AST, running on the stockmystCLI and themes — no custom server.Net diff: +2,506 / −8,879 across 55 files — roughly half the codebase removed.
The governing principle: three single sources of truth
astra.yaml(+universes/,results/)index.mdThe plugin is a pure projector: it renders the elements the author placed (neutral semantic AST any theme shows) and bakes a resolved data store for rich themes. It makes no authoring or styling decisions.
What changed
Removed (the generate-everything stack):
src/server/— the bespoke Express content server, routes, watcher, WebSocketsrc/cli.ts,src/theme/launcher.ts— the two-server boot CLI and theme launchersrc/transform/index.ts—buildAllPages/astraToMystASTwhole-document orchestrationsrc/doi/andsrc/papers/— custom DOI resolver/cache + paper backlinks (delegated to MyST)src/types/astra.ts,src/types/content-server.ts,src/utils/hash.ts— hand-mirrored types + content cachepage-shape,schema-coverage,server-routesKept / refactored into the plugin core:
src/index.ts— the plugin is the package entry (default export)src/loader.ts— one-file project loader via@astra-spec/sdk, deterministic on-demand artifact resolutionsrc/transform/*— the per-component renderers actually used by directives/rolessrc/transform/resolved-store.ts— bakes the resolved ASTRA model onto a hiddendiv.astra-storecarrier (per page), keyed by id, for rich themes@astra-spec/sdk— MySTRA defines none of its owntests/plugin-emission.test.ts+tests/loader-validation.test.tsAuthoring vocabulary — block directives (
astra:decision|output|finding|prior-insight|inputs|outputs|subanalysis), inline roles ({astra:decision}…), and live value interpolation ({astra:value}pulls real cells from result products at build time, so no measured number is hand-typed).Docs & packaging (recent commits)
npm install @astra-spec/mystra, reference by name inmyst.yml)mystra→@astra-spec/mystra, version reset to0.0.1SPEC.mdrewritten to the implemented design;STRATEGY-A-REFACTOR.mdrecords the full keep/refactor/remove rationaleOut of scope (follow-ups)
lightcone-astrarich theme (glyphs, hover cards, dependency graphs) — until it ships,book-themeis the clean baselineTest plan
npm run buildclean (no dead imports after removals)npm test— plugin-emission, resolved-store, and parser tests greenmyst starton an ASTRA project renders cleanly onbook-theme— figures load, numbers are live, noastra.yamlread by the server/theme🤖 Generated with Claude Code