Skip to content

fix: nest the decision/finding fallback inside the carrier node#11

Merged
EiffL merged 1 commit into
mainfrom
fix/nest-fallback-in-carrier
Jul 5, 2026
Merged

fix: nest the decision/finding fallback inside the carrier node#11
EiffL merged 1 commit into
mainfrom
fix/nest-fallback-in-carrier

Conversation

@EiffL

@EiffL EiffL commented Jul 5, 2026

Copy link
Copy Markdown
Member

Fixes #9.

For placed decisions and findings the plugin emitted the neutral fallback (the details/summary dropdown; the notes/scope paragraphs and evidence blocks) as siblings of the heading carrier. A rich theme overriding the carrier replaced only the heading, so the fallback still rendered and readers saw every decision and finding twice (see LightconeResearch/astra-theme#2, item 3).

Change

  • Decisions and findings now render as one div carrier bearing the <kind>-<id> identifier, with the entire neutral fallback nested as its children — the same pattern the output and prior-insight carriers already follow. A theme replacing the carrier replaces the fallback wholesale; nothing is left behind to double-render.
  • The div node is the one the stock :::{div} directive emits, so neutral themes render the children exactly as before, and the identifier still anchors cross-references.
  • data.tags moves from the heading to the carrier (the joinable node).
  • New carrierDiv() helper in ast-helpers.ts; carrier tests updated to pin the nesting so the sibling shape can't regress.

No changes needed in index.ts: class stamping (tagComponent), :label:/:class: overrides, and registry rendering all locate the carrier by identifier and pick up the wrapper automatically.

Theme follow-up (separate repo, deferred)

astra-theme registers heading[class*="astra-decision"] / heading[class*="astra-finding"]; those selectors need to move to a div bucket once the theme builds against this version. The components need no logic changes — they join by node.identifier and degrade via node.children (the degrade path improves: children are now the full fallback rather than the bare title).

Testing

  • npx vitest run — 94/94 pass, including the updated carrier-contract tests.
  • npx tsc --noEmit — clean.

🤖 Generated with Claude Code

Decisions and findings emitted their neutral fallback (details dropdown,
notes/scope/evidence) as siblings of the heading carrier, so a rich theme
overriding the carrier still rendered the fallback — every placed decision
and finding showed twice. Wrap the whole fallback in a single div carrier
bearing the <kind>-<id> identifier, the same pattern the output and
prior-insight carriers follow. Tags move from the heading's data slot to
the carrier's.

Fixes #9

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@EiffL

EiffL commented Jul 5, 2026

Copy link
Copy Markdown
Member Author

Verified end-to-end against astra-theme + the DESI DR1 BAO prototype (local dist/mystra.mjs build of this branch):

  • Decisions: rich panel renders from the new div carrier; zero stock fallback dropdowns left in the DOM (previously the theme hid them with a CSS stopgap — now they're gone at the AST level).
  • Findings: the double-render is gone — notes/scope text appears exactly once (this one had no theme-side workaround, so it's the big win).
  • Anchors: decision-<id> / finding-<id> land on the carrier div and cross-page #decision-… links still resolve.
  • vitest 94/94 + tsc clean on the branch.

Theme follow-up is done in astra-theme (uncommitted working tree): renderers registered under a div bucket with the old heading selectors kept for ≤ v0.0.5 back-compat, the decision panel's no-rationale branch no longer renders node.children (that would now nest the entire fallback inside the rich panel), and the CSS stopgap comment now marks it back-compat-only. LGTM.

@EiffL EiffL merged commit d6c6394 into main Jul 5, 2026
3 of 4 checks passed
EiffL added a commit that referenced this pull request Jul 5, 2026
…allback (#13)

Closes the metric leftover from #10 (see also
LightconeResearch/astra-theme#2, ecosystem notes).

A produced metric embed (:::{astra} outputs.<id>) rendered as a
collapsible key/value table on a 'details' carrier — a poor neutral
fallback, and a node type rich themes can't sensibly key on, so the
big-stat rendering never triggered even though the resolved store
already carries the parsed metric. An unproduced output embed was worse:
the pending admonition carried no identifier at all, so cross-references
and store joins had nothing to land on.

- A produced metric now renders as one div carrier (the #11 contract)
  bearing output-<id>, with a readable sentence fallback nested inside:
  "**<label>:** <value> ± <uncertainty> <unit>", built via readMetric.
  A JSON that isn't metric-shaped keeps the tabular fallback (wrapped in
  the same carrier).
- An unproduced output embed (any type) wraps its Pending Output
  admonition in the identifier-bearing carrier div: anchors resolve and
  rich themes can join the store entry (label, description, provenance)
  before the artifact exists.
- data / report types keep their current inline rendering.

Tests: metric carrier test now pins the div + sentence + no-details
shape; new unproduced-embed test pins the identifier + nested admonition
(101/101 pass, tsc clean).


Claude-Session: https://claude.ai/code/session_013EE6NiwH2UhVAUT6cdAQJ4

Co-authored-by: Claude Fable 5 <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.

Decision/finding fallback is emitted as siblings of the carrier → double render in rich themes

1 participant