Skip to content

refactor!: resolve publications through the ASTRA SDK - #25

Merged
EiffL merged 8 commits into
mainfrom
refactor/resolved-analysis-sdk
Aug 30, 2026
Merged

EiffL merged 8 commits into
mainfrom
refactor/resolved-analysis-sdk

Conversation

@EiffL

@EiffL EiffL commented Aug 28, 2026 •

Copy link
Copy Markdown
Member

Summary

  • replace MySTRA's custom YAML loader, resolved store, provenance reconstruction, and output aliasing with @astra-spec/sdk project resolution and canonical indexes
  • keep MyST roles and directives synchronous by emitting lightweight requests, then resolve the project once in a single asynchronous document transform
  • publish the SDK's exact ResolvedAnalysisBundle through a versioned, data-only carrier, with separately rewritten static artifact resources and SDK-collected citations
  • publish deterministic identity and display context on AST nodes so a theme can render rich previews without parsing labels, reconstructing provenance, or guessing routes
  • update authoring and theming documentation around canonical SDK paths, multi-page analysis navigation, live values, resolved universe state, and pending/inactive records

Publication contract

Every transformed page carries:

{
  schemaVersion: 'astra-publication-bundle.v1',
  activeAnalysisPath: string,
  bundle: ResolvedAnalysisBundle,
}

The bundle is passed through unchanged. MyST-rewritten artifact URLs remain separate and are rejoined by canonical outputPath plus the SDK cacheToken, so the theme does not need a parallel data model. Visible artifacts and hidden static-resource links are emitted relative to the current source page, including nested MyST pages, while SDK binding paths remain untouched.

The small SDK host cache records every file read, directory listing, and stat result used during project resolution. It deduplicates concurrent page builds while invalidating on source, universe, or artifact changes—including newly materialized outputs.

ASTRA component prose is inserted after MyST's document-level transformations, so MySTRA applies MyST's official math nesting, labeling, and KaTeX rendering passes at that boundary. Inline and display math therefore reach themes fully rendered, while malformed equations report through the page's normal VFile diagnostics.

Theme metadata boundary

Placed record carriers and inline record references expose only resolvable SDK identity:

{ kind, id, canonicalPath }

Analysis references use a deliberately separate address:

{ kind: 'analysis', id, analysisPath, href? }

href exists only when a concrete, unambiguous project.toc page maps to that analysis using MyST's route rules. No /<analysis-id> URL is invented. Active-page scope and route mapping share the same source-stem logic for Markdown, notebooks, TeX, and .myst.json pages.

Inline values additionally carry the relevant type, selection, unit, product, col, and filter strings when available. Optional values are omitted rather than serialized as empty or undefined compatibility fields.

Breaking alpha cleanup

This is a deliberate clean cutover with no legacy compatibility layer:

  • removes the author-facing astra:numref and custom astra:ref surfaces; explicit directive labels use standard MyST {ref}
  • removes the prior-insights and filter= aliases, author-addressable universe paths, and /static artifact fallback
  • removes guessed sub-analysis URLs and all legacy resolved-store/provenance code
  • emits only canonical SDK record paths on inline metadata; unresolved references fall back to neutral text without fabricated metadata

Verification

  • npm run typecheck
  • npm run build
  • npm run bundle, followed by a successful import of the standalone bundle
  • npm test — 72 tests
  • npm run docs:build — strict build, no issues
  • live DESI build — all 28 late output-caption equations render as KaTeX with no raw-TeX warning fallback
  • git diff --check

Companion consumer work:

EiffL added 2 commits August 28, 2026 18:38
Signed-off-by: EiffL <fr.eiffel@gmail.com>
Signed-off-by: EiffL <fr.eiffel@gmail.com>
Signed-off-by: EiffL <fr.eiffel@gmail.com>
@EiffL
EiffL force-pushed the refactor/resolved-analysis-sdk branch 2 times, most recently from 415684c to a5e6c87 Compare August 28, 2026 19:29
Signed-off-by: EiffL <fr.eiffel@gmail.com>
@claude

claude Bot commented Aug 28, 2026

Copy link
Copy Markdown

Code review

No issues found. Checked for bugs and CLAUDE.md compliance.

Quality pass over the branch — no behavior changes.

Reuse:
- hrefForSlug called myst-common's slugToUrl instead of forking MyST's
  slug -> URL rule, which fails silently as wrong hrefs when MyST changes.
- Deleted artifactUrl, a pure pass-through left over when the /static/
  fallback was removed.
- Collapsed the metric field aliases (error -> uncertainty, units -> unit)
  inside readMetric rather than at each of four call sites.
- Shared the page -> analysis scope rule between the href map and
  active-page resolution, which had drifted into two spellings.

Simplification:
- One inactiveUnderUniverse() helper for a sentence written four times.
- renderFinding's `parts` is required; the fallback branch was unreachable.
- Dropped the sentinel/stringify layering on the project cache key.

Efficiency:
- resolveScope rebuilt five id->record maps on every {astra} reference.
  Split out a memoized ScopeCore keyed on ResolvedProject identity, so
  invalidation stays free while the per-pass parts are still per call.
- analysisPageHrefs and collectCitedDois are page-independent but ran once
  per page; the former re-read myst.yml and every TOC page's full source,
  making builds O(pages^2) in file reads. Both memoized per project.
- Restored the mtime-revalidated table parse cache dropped in the refactor,
  so repeated references to one CSV parse it once. The row cap stays in the
  render layer, where it moved deliberately: {astra:value} needs full rows.
- The freshness cache held the full text of every spec file for the process
  lifetime and byte-compared them per page; it now stores a digest.
- Scope carries resultUrl instead of rebuilding it at three call sites.

Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_013ud8wSfVjAMPDVB5txwzTi
Signed-off-by: EiffL <fr.eiffel@gmail.com>
Comment thread docs/authoring/block-embeds.md Resolved

@EiffL EiffL left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

Comment thread docs/reference/theming.md Resolved
Comment thread docs/getting-started.md Resolved
EiffL added 3 commits August 29, 2026 21:16
Signed-off-by: EiffL <fr.eiffel@gmail.com>
Signed-off-by: EiffL <fr.eiffel@gmail.com>

@EiffL EiffL left a comment

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM

@EiffL
EiffL merged commit 8b7dd79 into main Aug 30, 2026
7 of 8 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant