Skip to content

Redesign ASTRA referencing around a unified path grammar#8

Open
EiffL wants to merge 7 commits into
mainfrom
redesign-astra-references
Open

Redesign ASTRA referencing around a unified path grammar#8
EiffL wants to merge 7 commits into
mainfrom
redesign-astra-references

Conversation

@EiffL

@EiffL EiffL commented Jun 30, 2026

Copy link
Copy Markdown
Member

Summary

Redesigns how authors reference ASTRA components, from the ground up, to follow standard MyST conventions for roles and directives. Replaces the previous per-kind directives/roles ({astra:decision}, :::{astra:output}, …) and the separate dotted anchor grammar ([](#outputs.x)) with a single slash-path grammar that mirrors astra.yaml, addressed by one {astra} role (inline) and one {astra} directive (block) — the same way MyST reuses {math} as both.

Design rationale and full authoring docs: see design_proposal.md and the rewritten Authoring section of the README.

The model

A path is a slash route through the analysis tree (the astra.yaml structure):

outputs/hubble_diagram                  an output
decisions/algorithm/options/gp          a child (option of a decision)
findings/sig/evidence/fig1              a child (evidence of a finding)
reconstruction/outputs/xi               a sub-analysis (analyses/ implied)
outputs                                 a whole collection (a registry)
  • Inline: {astra}`outputs/hubble_diagram` (+ <text> display override)
  • Block: :::{astra} outputs/hubble_diagram :::
  • Variants (MyST colon convention): {astra:num} (native numref), {astra:cite} / {astra:cite:t} (citations from DOI evidence), {astra:value} (live number / decision selection)
  • Native scheme: [](#astra:outputs/x), ![](#astra:outputs/x), :::{figure} #astra:outputs/x :::

What changed

  • New src/path.ts — parses/resolves the unified grammar (collections, scope steps, option/evidence children, registries, leading /, ../).
  • {astra} directive dispatches elements, children, whole collections (registries), and bare sub-analyses; options :label: :caption: :compact: :show:/:hide: :universe: :class:.
  • Roles: {astra} (store-driven hover card), {astra:num}, {astra:cite}, {astra:cite:t}, {astra:value}.
  • #astra: anchor resolver (prose.ts) — page-relative, with ../ and cross-page links; figure embeds for in-scope outputs.
  • ASTRA narrative removal — the latest ASTRA drops the narrative section, so sub-analysis card summaries and #narrative.* anchors are gone.
  • Docs — rewritten README authoring section; design_proposal.md added.
  • Testsplugin-core / prose suites rewritten for the new syntax; new tests/path.test.ts.

Notes / scope

  • Role & directive paths resolve from the root analysis; the #astra: link scheme resolves relative to the page (directives have no page context at run time). Documented in the README.
  • The rich-theme contract (resolved store, astra-* classes, cross-scope merge, DOI citation registration) is preserved; finding-evidence DOIs are now also registered.

Verification

  • npm run typecheck
  • npm test ✅ — 105 passed
  • npm run build + npm run bundle

🤖 Generated with Claude Code

EiffL and others added 7 commits June 30, 2026 14:33
Replace the per-kind directives/roles and the dotted anchor grammar with a
single slash-path grammar that mirrors astra.yaml, addressed by one {astra}
role (inline) and one {astra} directive (block) — the MyST way — plus
colon-namespaced variants and a native #astra: cross-reference scheme.

- new src/path.ts: parse/resolve the unified grammar (collections, scope
  steps, option/evidence children, registries, leading-/ and ../)
- {astra} directive renders elements, children, whole collections
  (registries), and bare sub-analyses; options label/caption/compact/
  show/hide/universe/class
- {astra} role is store-driven; {astra:num} emits a native numref
  crossReference; {astra:cite}/{astra:cite:t} emit MyST citations from DOI
  evidence; {astra:value} reads a table cell, metric, or decision selection
- #astra:<path> links resolve to crossReferences / cross-page links and
  ![](#astra:...) figure embeds, page-relative with ../ support
- account for ASTRA dropping the narrative section (no card summaries,
  no #narrative anchors)
- rewrite README authoring docs; add design_proposal.md
- rewrite test suites + add tests/path.test.ts (105 tests pass)

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
- resolveInlineRef: drop a redundant resolveScope for bare sub-analysis
  references (the caller already resolved into the sub; read its name)
- universes/<id>: resolve the universe once in the directive instead of
  re-resolving inside renderElement
- renderUniverse: build the table with the ast-helpers constructors
- extract renderDecisionBlock to dedupe the decision render in element +
  registry paths
- cache slugParts on Scope, removing repeated slug.split('/')
- parseAstraPath: read the analyses branch left-to-right

No behavior change; 105 tests pass.

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
MyST's reference resolver fills the number/label for `link` nodes during its
own pipeline but leaves plugin-injected `crossReference` nodes unresolved
(LaTeX `\ref{undefined}`, no figure number). Found while porting the DESI DR1
example: every {astra:num} and #astra: in-page reference rendered undefined.

Emit `link` nodes (url `#<identifier>`) instead so MyST resolves them natively:
- {astra:num} role → link (empty/%s text filled by MyST as "Figure N")
- the #astra: anchor transform's in-page verdict → link to #<identifier>

Tests updated to assert the link form; 105 pass. Verified against the example:
numbered figure/table references now resolve.

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Match MyST's actual role name ({numref}) rather than inventing a `num`
abbreviation — the redesign's whole premise is to mirror MyST conventions, and
unlike cite:p/cite:t (which abbreviate nothing) `num` shortens the established
full name for no benefit.

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Bump from 0.0.3 to the latest 0.0.5. The narrative section was removed from
ASTRA in this range, so the SDK no longer exports the narrative validators
(validateNarrativeAnchors, checkNarrativeCoverage, validateNarrativeSections);
drop them from loader validation (MySTRA was already narrative-free). Typecheck
clean, 105 tests pass.

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
…depth)

- The resolved-store carrier set a fixed `astra-store` identifier on every
  page, colliding across the project ("Duplicate identifier"). It's selected by
  its `.astra-store` class, so drop the identifier.
- Decisions rendered as h4; placed under a typical `## ` section that skips a
  level (MyST "missing heading depth 3"). Render at h3 — contiguous, and the
  same level findings already use.

105 tests pass; the DESI example now builds warning-free.

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
The rich theme locates the resolved-store carrier by its `astra-store`
identifier; dropping it (to silence the advisory "Duplicate identifier in
project" warning) left the theme with no store to join, so inline hover preview
cards stopped rendering. The identifier is load-bearing — restore it and keep
the (benign, always-present) duplicate-identifier warning. The decision
heading-depth fix from the same batch is unrelated and retained.

Signed-off-by: Francois Lanusse <fr.eiffel@gmail.com>
Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
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