feat(library): inline cross-links via bosco: protocol #88
No reviewers
Labels
No labels
area: arcade
area: art-studio
area: calendar
area: chapel
area: content
area: design
area: field-guide
area: infra
area: library
area: os
area: portal
area: sync
area: typing
blocked
breaking
bug
content: approved
content: changes-requested
content: drafting
content: needs-doctrinal-review
content: needs-review
dependencies
documentation
duplicate
enhancement
epic
github_actions
good first issue
help wanted
invalid
javascript
needs-triage
priority: high
priority: low
priority: medium
question
type: enhancement
type: feature
type: fix
type: perf
type: security
wontfix
No milestone
No project
No assignees
1 participant
Notifications
Due date
No due date set.
Dependencies
No dependencies set.
Reference
Bosco/bosco!88
Loading…
Add table
Add a link
Reference in a new issue
No description provided.
Delete branch "feat/library-cross-links"
Deleting a branch is permanent. Although the deleted branch may continue to exist for a short time before it actually gets removed, it CANNOT be undone in most cases. Continue?
The Library — inline cross-links (v0.3.0 PR2b-i)
Authors can now link from one article's prose to another Library topic with a
bosco:protocol:A build-time remark plugin rewrites
bosco:category/slugto the real prerendered route/library/category/slug/after validating the target ships in this build — the inline sibling ofthe frontmatter
related/See-alsovalidateCrossLinks. A dangling or (in production) unreviewedtarget fails the build. Rendered links are real
/library/**anchors, so the desktop's delegatedhandler opens them in-window while deep-links/no-JS follow the route.
Split from PR2b
A design workshop (3 proposals → synthesis → 3 critics) recommended splitting the original PR2b: the
risk is wildly asymmetric. This PR is the low-risk foundation + cross-links; the glossary +
toggletip + doctrine gate (where all the a11y/escaping/doctrinal-review risk concentrates) is the
focused PR2b-ii that builds on this foundation.
Two load-bearing facts the design surfaced (and this PR proves)
.js, not.ts.svelte.config.jsis imported by a raw Nodeimport()that can't transpile TypeScript, sogate.js/catalog.js/remark-bosco.jsare ESM.jswith JSDoc types (checked viacheckJs).schema.tsre-exports the gate primitive fromgate.js(single source), so existingfrom './schema'imports are unchanged.globalThis.plugin.ts(esbuild-inlined into the Viteconfig) and
remark-bosco.js(loaded on-disk bysvelte.config.js) are different instances, so amodule-level variable wouldn't be shared. The plugin's
configResolvedpopulatesglobalThis[Symbol.for('bosco.content.catalog')](gate + shipping topic paths) before any Markdownis transformed; remark reads it, and
requireGate()throws fail-closed if the catalog is unset.What's in it
gate.js(single-source gate primitive),catalog.js(passive globalThis store),remark-bosco.js(validate + rewrite
bosco:, throw on external URLs — defense-in-depth;guard:externalstaysauthoritative),
plugin.ts(populate the catalog inconfigResolved, re-populate on HMR), themdsvex wiring, tokenised
.art-body astyling (this PR introduces the first in-prose link), the democross-link, the CONTRIBUTING governance rule, and
remark-bosco.test.ts.Verified
/library/world/printing-press/, no rawbosco:link leaks)and negative (a dangling
bosco:fails the build with a clear, file-anchored error).malformed throw, external throw, fail-closed, base assertion), 18 e2e (+2 cross-link: standalone +
in-window intercept), lint clean.
--sel-deep+ underline at 7.34:1 on--paper, opens in-window.