Add build-story: deterministic reader-facing story page from the published chain - #25
Merged
Conversation
…ished chain scripts/build_story.py turns a published FORRT chain — or a research synthesis of several chains — into a self-contained HTML article, every value read verbatim from the signed nanopublications (nothing invented). It is the reader-facing companion to build-chain-draft, and like it runs off Claude's tokens. - pixi run build-story reads the chain apex from nanopubs/PUBLISHED.md (the Research Synthesis if published, else the Replication Outcome), fetches the constellation, and writes blog/index.html. Single-chain vs synthesis is auto-detected. - Both shapes carry the Science Live palette, an ORCID byline, a prominent citation, chips that link to the nanopub asserting each value, and a References & citations block. Self-contained output: display font embedded, headline figure downscaled and base64-inlined (Pillow), so it renders offline / in a Zenodo archive / on Pages. - scripts/story_assets/base.css holds the stylesheet (never edited per project). - Offline unit tests for the pure helpers; docs/story-page.md documents usage and where to publish (GitHub Pages + Zenodo; the platform /np/story route is the canonical hosted mirror).
… button
- jupyter-book.yml builds the story page as part of the Pages deploy and serves it
at /blog/ on the same site as the book (best-effort: skipped when the chain is not
published or SCIENCELIVE_API_KEY is unset, so it never fails the book deploy).
Re-running the workflow is how you regenerate the blog from the current network.
- A static page cannot securely trigger CI, so the toolbar now links to the live
version on the Science Live platform ('View on Science Live') instead of a disabled
'Sign in to regenerate' button.
- Endpoint env reads via 'or' so an empty GitHub Actions vars.SCIENCELIVE_API falls
back to production rather than becoming an empty string.
…CELIVE_PLATFORM) Defaults to production; a dev-network replication sets SCIENCELIVE_PLATFORM to its dev platform host so the link resolves to the right place.
An opt-in layer on top of the deterministic Record tab. If nanopubs/audience.json exists, the page gains one tab per audience — each banner-labelled AI-generated, with a recommended reading level, an accessible overview image, and an 'at a glance' infographic whose colours and ✓/✗ are taken from the signed verdicts (only the lay labels come from the AI, so the graphic is accurate by construction). No file → the page is the single Record tab, unchanged. - audience.json is produced ONCE at build time by the new .claude/agents/audience-writer agent (a constrained plain-language rewrite of the record's own text); baked into the static HTML, so the reader spends no tokens and nothing AI-written touches the Record. - Tab icons are inlined Font Awesome 6 (CC BY 4.0) — the Science Live icon family — kept self-contained (no CDN). The technical result plots stay Record-only; lay tabs reuse only the accessible overview figure. - nanopubs/audience.json.example documents the shape; docs/story-page.md documents the flow; offline tests cover the glance, tab bar, icons and audience loading.
… rebuild it) Serve whatever blog/index.html exists — freshly built, or a committed snapshot — so the page shows even when CI cannot rebuild it; no blog/ at all deploys the book alone.
The 'aggregated from the platform's per-nanopublication displays · nothing invented' banner was a leftover from the mockup (class=mockbar). Its message is already carried, in a reader-optional place, by the 'How this page is made' popup — so the always-on uppercase strip was redundant and competed with the headline for the top of the page. Removed from both render paths.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
What
A new deterministic step that turns a published FORRT chain — or a research synthesis of several chains — into a self-contained HTML article you can send a colleague to read, with every value taken verbatim from the signed nanopublications. It is the reader-facing companion to
build-chain-draft, and like it runs off Claude's tokens.How it works
nanopubs/PUBLISHED.md— the Research Synthesis (step 08) if published, else the Replication Outcome (step 05) — fetches the constellation, and rendersblog/index.html.View*components show (same field sets, labels, citation rule), restyled into an article; absent fields are omitted, never filled in.Files
scripts/build_story.py— the generator (handles single chain + synthesis)scripts/story_assets/base.css— the stylesheet, carrying the Science Live palette (never edited per project)tests/test_build_story.py— offline unit tests for the pure helpers (prose/label/apex logic); importing the module needs no API keydocs/story-page.md— usage + where to publish (GitHub Pages + Zenodo; the platform/np/storyroute is the canonical hosted mirror)pixi.toml—pillowdependency (already resolved via matplotlib) +build-storytask;CLAUDE.mddoc-map row + Phase 5 noteTesting
pixi run -e tests test→ 120 passed (13 new).Notes for review
SCIENCELIVE_APIoverrides it (dev testing).blog/is committed by the researcher after running the task (not produced in this template PR).