Specs
Draft 63
SPEC-007 main
Local Runes — Declarative Rune Extension (v1) SPEC-010 main
Theme Studio — AI-Powered Theme Generator apps/theme-studio — Dependencies: @refrakt-md/transform, @refrakt-md/lumina, @refrakt-md/runes, @refrakt-md/svelte, @refrakt-md/ai
32/34 criteria
SPEC-023 main
Storytelling World Engine Cross-page pipeline hooks, entity graph, auto-linking, validation, and CLI tooling for the @refrakt-md/storytelling package — turning isolated rune pages into a navigable, interconnected world bible.
SPEC-029 main
File-Derived Timestamps for Runes Expose file-level created and modified timestamps as Markdoc variables so any rune can consume them as attribute defaults, with explicit attribute values taking precedence.
SPEC-031 main
Vite Plugin — Framework-Agnostic Rune Integration A standalone @refrakt-md/vite plugin that lets developers use refrakt runes in existing Vite-based projects without adopting the full refrakt site editor or routing system. Complements SPEC-030 (Framework Adapter System) by providing a lighter-weight, framework-agnostic entry point.
0/6 work items
SPEC-034 main
Theme Structural Template Language (Design Exploration) A design exploration of a spatial template syntax for theme developers to express structural overrides — compiled to the declarative RuneConfig model defined in SPEC-033. This is not a committed implementation. It documents a possible future authoring surface so the idea is preserved and can be revisited if real theme development reveals the need.
SPEC-035 main
Multi-Language Support A locale-aware string resolution system enabling Refrakt sites to render UI text, labels, accessibility strings, and structural headings in any language.
SPEC-036 main
Claude Code Skills and Hooks for Plan Workflow Replace procedural CLAUDE.md instructions with Claude Code skills (custom slash commands) and hooks (automated enforcement) to make the plan workflow invocable, context-efficient, and enforceable.
SPEC-038 main
Git-Native Entity History Derive structured lifecycle timelines for plan entities from git history — attribute transitions, criteria progress, and resolution events — surfaced through the CLI and as a site rune.
SPEC-039 main
Plan Package Onboarding & Conventions Review Review and improve the @refrakt-md/plan package's conventions, folder structure, and onboarding experience. Three concerns drive this spec: the package is currently coupled to Claude Code as an AI tool, the folder naming convention uses singular nouns where plural would be more natural, and there is no path for users who already have planning documents to adopt the system.
SPEC-042 main
Plan Target for create-refrakt Add a planning-only scaffold option to create-refrakt so users who want to adopt refrakt primarily as a plan management tool have a one-command entry point, matching the experience for sites and themes.
SPEC-043 main
Refrakt MCP Server A single @refrakt-md/mcp package that exposes the refrakt CLI as a Model Context Protocol server, so AI agents can call refrakt operations through typed tools and structured I/O instead of shelling out and parsing text.
0/18 criteria
0/9 work items
SPEC-044 main
Agent content rendering and validation tools Tools and resources that close the agent's content-authoring inner loop. Today an AI agent writing refrakt content can read the rune reference, inspect a single rune in isolation, and run the build — but there's no way to render or validate an arbitrary Markdown snippet without the build, and no structured listing of the site's pages.
0/11 criteria
SPEC-045 main
Plan agent ergonomics Sharpen the plan tools for the workflow CLAUDE.md actually prescribes — pulling context before starting work, checking off many criteria when finishing, and trusting that referenced IDs are real.
0/11 criteria
SPEC-046 main
Navigation structure Extend the nav rune so a single content model expresses sidebar, header, footer, and section-landing navigation — with collapsible groups in the sidebar, dropdown menus in the header, column grids in the footer, and card grids on landing pages. One authoring vocabulary, four contextual renderings.
0/20 criteria
SPEC-047 main
Sequential page navigation Add a pagination rune for prev/next links in sequential reading flows — tutorials, ordered docs, recipes. Derive sibling order automatically from the page tree (or any explicit nav rune that defines order), with an escape hatch for hand-authored prev/next.
0/13 criteria
SPEC-049 main
Spec lifecycle and PR linkage Close the loop between a spec, the work that implements it, and the PRs that ship it — so a reader can answer "is this built, and is it available to users?" without grepping prose. Also tidies up an unrelated lifecycle gap in ADRs while we're in the neighborhood.
0/14 criteria
SPEC-050 main
Refrakt Brand Logo — Prism Redesign As refrakt closes in on v1.0, the brand mark deserves a refresh. The next logo should be a monochrome flat icon — something that reads instantly at favicon size, scales cleanly to hero size, and feels honest to the product.The brand metaphor we keep coming back to is a prism: refrakt takes one input (markdown) and refracts it into many outputs (themes, layouts, components, frameworks). Two prism variants are captured below for comparison. Both are equilateral triangles pointing downward, drawn in white on the lumina dark navy background (--rf-color-bg = #152238).
SPEC-051 main
Lumina neutral default & tideline preset Reposition Lumina from "refrakt's opinionated cream-and-navy theme" to "refrakt's flagship theme, neutral by default, with named presets for those who want a starting palette." The current cream-and-navy values move out of Lumina's defaults into a named preset (tideline) that anyone can opt into. The defaults become a deliberately quiet warm-neutral so refrakt's documentation surface reads as a canvas any brand could occupy.This is primarily a positioning decision. SPEC-048 already designed the preset mechanism as plain data merged in order; this spec is about what we ship in that mechanism, not new infrastructure. It depends on SPEC-048 being implemented.
0/14 criteria
SPEC-052 main
Per-page and per-subtree tint cascade Extend the existing per-rune tint and tint-mode attributes to cascade through layout files and individual pages, so authors can express "lock all marketing pages to dark mode" or "this single page uses the hero-brand tint preset" without writing per-rune attributes everywhere. Reuses the layout cascade refrakt authors already work with, rather than introducing a separate route-rules config surface.Depends on SPEC-048 (typed token contract, tint system, theme.colorScheme field at site level).
0/10 criteria
SPEC-053 main
Tint shape alignment Align the TintDefinition shape with the rest of the design token contract. The current tint vocabulary uses field names that are inconsistent with the token contract (primary in tints means body text; primary in tokens means the interactive accent — a direct collision) and a top-level mode field that's structurally awkward. This spec realigns tint field names to match the token contract, simplifies mode, adds an extends mechanism, and tightens the project-level type from Record<string, unknown> to a proper TintDefinition.The CSS bridge implementation (packages/lumina/styles/runes/tint.css) is intentionally not changed by this spec — it's well-designed and only needs the rename applied. This is a vocabulary refactor, not a behaviour change.Lands in v1.0 as a breaking-change cleanup. Depends on SPEC-048 being implemented.
0/12 criteria
SPEC-056 main
Syntax token contract extension Widen the SyntaxTokens contract from its current 9 roles to a tiered shape that can faithfully carry palettes derived from well-known Shiki / VS Code themes (Nord, Dracula, Solarized, Tokyo Night, Catppuccin, GitHub, …) as refrakt presets. Adds a small set of optional roles with documented fallbacks to existing core roles, so simple presets (e.g. niwaki) keep their current minimal shape and richer presets gain the headroom they need.Beyond the syntax foreground, the spec also formalises two adjacent surfaces that fall out of importing integrated palettes:
SPEC-057 main
Curated syntax preset lineup — Phase 1 Ship six widely-recognised, well-licensed syntax palettes as first-party refrakt presets — Dracula, Solarized, Catppuccin, Tokyo Night, One Dark, Gruvbox — following the pattern established by WORK-220 (Nord) under SPEC-056. Each palette becomes a ThemeTokensConfig module under packages/lumina/src/presets/, gets a documentation page under /themes/, and is registered in the refrakt docs site's theme.tints for live showcase rendering. No architectural changes — this spec is the application of SPEC-056 to a curated lineup.This is Phase 1 of a longer roadmap. Phase 2 candidates (GitHub Light/Dark, Ayu, Rosé Pine, Monokai, Kanagawa, additional Catppuccin and Tokyo Night flavours) are listed in "Out of scope" so the door is open without committing to them now.
SPEC-058 main
Framework adapter parity with the SvelteKit reference @refrakt-md/sveltekit is the adapter the refrakt documentation site itself ships on, so it's the only adapter that gets exercised end-to-end on every release. Over the v0.14.x patch line the SvelteKit plugin grew a number of capabilities — site-level token-overrides CSS (SPEC-048 + SPEC-056), SEO meta enrichment from site-level config (siteName, baseUrl, defaultImage, logo), CSS tree-shaking by used-rune analysis, build-time pipeline-stats output, SecurityPolicy plumbing, Markdoc variables, and content HMR — that were never threaded through Astro, Nuxt, Next.js, Eleventy, or the pure-HTML renderer. The result is silent: those adapters happily read refrakt.config.json, ignore the new fields, and produce pages that work but miss the overrides + meta tags + optimizations + dev-loop the same config produces under SvelteKit.This spec closes the gap. It is application work — no new design, no new contracts. Every capability it brings to the other adapters already exists, working, in @refrakt-md/sveltekit. The job is extraction, sharing, and per-adapter wiring along the path each adapter natively uses.
SPEC-059 main
Adapter testing infrastructure and drift prevention The catalyst for SPEC-058 was that capabilities accreted onto @refrakt-md/sveltekit over the v0.14.x patch line and silently failed to reach the other five adapters. The refrakt documentation site only exercises SvelteKit on every release, so every other adapter is implicitly trusting "looks the same in the code" as a parity guarantee — and the cost of that trust came due as a six-feature gap.This spec defines the testing infrastructure that prevents the next round of drift. The shape: shrink the per-adapter code surface as far as is reasonable, then catch the residual drift with cheap automation rather than expensive deployments. A live-deployment-per-adapter validation strategy was considered and deferred — the maintenance cost of keeping five hosted sites in sync is the very class of drift this spec is trying to detect.This is implementation-deferred work. The milestone of SPEC-058 ships first; this spec captures the test infrastructure that should land after that parity work is in place, when the per-adapter surfaces are at their narrowest and snapshotting them is most stable.
SPEC-060 main
Drawer rune A modal panel rune that holds richer content than a tooltip but lighter than a navigation away. Inspired by Linear's pattern where in-page references expand to explainer panels rather than forcing the reader to leave context.The drawer rune is body-only: it declares an addressable panel by ID, and any {% ref %} to that ID becomes a trigger. Triggers can appear anywhere — in prose, in a navbar, in multiple places at once — and the inline-flow case ("spec mentioned mid-sentence") is automatic because xrefs are already inline. Built on <dialog> for accessibility; progressive enhancement renders the body as a visible in-flow block without JS.
0/28 criteria
SPEC-061 main
Content variable surface — completing $page, $file, and rationalizing the namespaces Audit and complete the author-facing Markdoc variable surface exposed by refrakt's content pipeline. The pipeline today exposes $frontmatter.*, a partial $page.*, and a partial $file.* — but $page.* is undersized (no dir, slug, title, and the existing filePath key is misnamed), and $file.* lacks a project-root file path that consumers like the snippet rune need for disk-relative resolution. Extend both namespaces, document the whole public surface clearly, and settle the convention that double-underscore-prefixed variables are pipeline internals.The page-vs-file split matters: $page.* describes the page as a content artifact (its place in the content tree, its URL, its slug); $file.* describes the source file as a disk artifact (where it lives on disk, when it was committed). The two have different roots of reference — $page.path is relative to the content directory, $file.path is relative to the project root — and consumers reach for whichever frame matches their concern.The headline motivation is the view-source pattern from SPEC-062 (which needs $file.path for snippet's project-root-sandboxed resolution), but the rationalization benefits every rune that wants page or file context.
0/24 criteria
SPEC-062 main
Snippet rune A rune that renders the contents of a file (path relative to the project root) as a syntax-highlighted code block. Solves the recurring documentation problem of keeping inline code examples in sync with actual source files, and incidentally enables the view-source-of-current-page pattern via {% snippet path=$file.path /%}.Core rune (lives in @refrakt-md/runes). "Embed a file as a code block" is a universal primitive — useful in tutorials, marketing pages, blogs, world-building sites, anywhere an author wants build-time file embedding. Sits naturally next to codegroup, compare, diff, and datatable in the "Code & Data" category rather than in any plugin's specific surface.Composes with {% drawer %} from SPEC-060 for the side-panel view-source pattern, depends on $file.path from SPEC-061 for the self-referential case, and — via a pre-resolve preprocessing step — composes transparently inside container runes that consume fenced code blocks ({% codegroup %}, {% diff %}, and any future fence-consuming rune). See Composition below. (Note: $file.path is the project-root-relative path, which matches snippet's project-root sandbox. $page.path exists too but is content-root-relative and the wrong frame for snippet's resolver.)
0/34 criteria
SPEC-063 main
Configurable file roots A generic mechanism for registering named directories (file roots) in refrakt.config.json and from plugins. Once registered, file-reading runes can resolve paths via a namespace:filename syntax that anchors at the named root. Backwards-compatible: unprefixed paths keep their existing per-consumer resolution (Markdoc partials from each site's _partials/, snippet from the project root); prefixed paths route through the file-roots registry.The v1 consumer is Markdoc partials, extending {% partial %} to resolve namespaced files. The mechanism is deliberately not partial-specific — the snippet rune (SPEC-062) plans to consume the same resolver when its v2 lands, and any future file-reading rune (build-time includes, generated-content embeds, etc.) plugs into the same surface. One resolver, multiple consumers.The motivating use cases are (a) sharing partials across sites in a multi-site monorepo, and (b) enabling plugins to ship content files reachable from user sites — the latter is what unblocks the expand rune in SPEC-066 (via the plan plugin's registration work in SPEC-064), since plan content lives outside the site content tree.
0/20 criteria
SPEC-064 main
Plan plugin — unconditional entity registration Extend the plan plugin's pipeline register hook to scan the configured plan directory at content-load time and register every plan entity into the EntityRegistry, regardless of whether plan files are part of the site content tree. Each registration includes the source file path and an extractor function — enough information for both xref (linking) and expand (inline substitution, see SPEC-066) to operate uniformly via the registry.This is the companion implementation work for the expand rune (SPEC-066). expand needs every embeddable entity to be in the registry; for plan content that lives outside the site's content tree, the registry is empty today, so without this change expand can't function for plan IDs in projects that don't publish plan to their site.
0/14 criteria
SPEC-065 main
Configurable xref resolution Extend the xref postProcess resolver with a configurable URL-template layer so refs to entities outside the local EntityRegistry can resolve to real links via project config. Backwards-compatible with the existing registry-based resolution; entirely declarative and third-party-neutral. Refrakt itself stays out of the business of knowing about specific external systems — users supply their own patterns.The motivating case is plan content hosted externally (refrakt trace, self-hosted plan publishers, hypothetical competitors), but the same mechanism cleanly handles GitHub issues, Linear tickets, RFCs, npm packages, Wikipedia entries, DOI citations, and anything else with a deterministic URL scheme. The expand rune from SPEC-066 also consumes this chain for its canonical-link affordance — entities embedded inline get a "View canonical" link resolved by the same patterns that drive {% ref %}.
0/25 criteria
SPEC-066 main
Expand rune A core rune that takes a registered entity ID and substitutes the entity's source content inline. Generic over entity types — works for plan specs, characters, organizations, events, or anything else a plugin registers with embeddable content. Symmetric with xref: same registry, same lookup chain, different output mode (inline content rather than a link).The motivating use case is in-context plan-content previews via {% drawer %}{% expand "SPEC-023" /%}{% /drawer %}, but the same machinery serves any plugin that registers entities with extractor information. The accompanying plan-plugin work to scan and register plan entities unconditionally is captured in SPEC-064.Lives in @refrakt-md/runes alongside xref. The name expand avoids collision with the existing {% embed %} rune for media URLs.
0/35 criteria
SPEC-067 main
"See it in action" — site-as-showcase introduction article cluster A site-side deliverable, not an engine spec: a guided introduction article (or short cluster) that uses the refrakt site itself as the showcase. The reader doesn't watch a demo — they walk through the live site with the article as a tour guide, discovering that every primitive they encounter (nav, drawer, xref, expand, plan content, code embeds) is the system working on itself.This spec is a placeholder to capture the creative beats while we finish the engine work that unblocks it (SPEC-060, SPEC-062, SPEC-066, SPEC-061, SPEC-065). It will be promoted to draft and fleshed out once those land.
SPEC-068 main
Adapter HMR contract for arbitrary file dependencies A deferred follow-up to SPEC-062 (snippet rune) and SPEC-063 (configurable file roots). Both ship initially without HMR support for files outside the content tree — host pages don't auto-refresh when a referenced source file or namespaced partial changes during dev. This spec will define the dependency-tracking model and per-adapter integration that closes the gap.This is a placeholder to capture the design direction so we don't relitigate it later. It will be promoted to draft once SPEC-062 and SPEC-063 have shipped and real usage informs the actual contract.
SPEC-069 main
Plugin-contributed routes & declarative entity routing A mechanism for getting content into a refrakt site from sources that don't live in the content tree — local plan files, external CMSes, databases, issue trackers. It operates on two orthogonal axes:
0/30 criteria
0/3 work items
SPEC-070 main
Collection rune A generic core rune that renders a list, table, or grid of registry entities — the plural counterpart to {% ref %} (one entity → a link) and {% expand %} (one entity → inlined content). Where those consume a single entity, collection queries the registry for many and projects them into a chosen layout, with filter / sort / group / limit and declarative field selection.Generic over entity type: works for plan specs, storytelling characters, places events, design tokens, commerce products, externally-registered CMS / database rows — anything in the EntityRegistry. Replaces hand-maintained lists that mirror structured data with a live query, the same way {% backlog %} does for plan content — but for every entity type, core and plugin alike.
0/26 criteria
1/7 work items
SPEC-071 main
Plan site scaffolding Turn a project's plan/ directory into an ordinary refrakt site — built by the standard content pipeline, using entityRoutes (SPEC-069) for per-entity detail pages and collection (SPEC-070) for dashboards and listings — and retire the bespoke plan build / plan serve commands. Ship it as a create-refrakt scaffold, and prove it by converting refrakt's own plan/ into a site.This spec is the concrete realization of SPEC-069's Replacing plan-serve section. It is deliberately a proof-of-practice: if entityRoutes + collection can fully replace the hand-rolled plan SSG, the two specs are validated against a real, demanding consumer, and we delete code rather than add it.
0/9 criteria
0/4 work items
SPEC-079 main
Semantic header zones + per-zone layout primitives for metadata-bearing runes Refactor how metadata-bearing runes (plan entities — work, bug, spec, decision, milestone — and any future card-shaped rune) declare their header content and how themes render it. Today the plan plugin's theme config bakes both the data manifest (which fields, types, sentiments) and the rendering shape (flat chip rows, left/right justified for the "primary" header) into a single structure tree. The badge styling has drifted between standalone {% badge %} and entity-header badges, the rendering shape is locked at the plugin layer, and the positional names (header-primary / header-secondary) bury the actual semantic roles. Split the concerns: plugins declare a meta-field manifest + semantic zones; themes pick a layout primitive per zone; the engine glues them.
0/14 criteria
9/9 work items
SPEC-080 main
Block-and-layout rune assembly model Refine the SPEC-079 zone model into a smaller, orthogonal contract for how metadata-bearing and media-bearing runes are assembled. A rune transform emits a tree of named blocks; the theme projects metadata blocks from a field manifest and composes the final tree by placing block names into containers. Field shape (chip vs bare), block grouping, layout geometry, and final placement become four independent axes instead of the overlapping zones / zoneLayouts / contentSlots / order / zoneHost / zoneHostPlacement surface that has accreted on RuneConfig.This supersedes the placement-related parts of SPEC-079 (zones shape, zoneHost, zoneHostPlacement, eyebrow left/right slots). The data-manifest idea (metaFields) and the plugin-declares-data / theme-declares-presentation split from SPEC-079 are kept and extended.
7/7 work items
SPEC-081 main
Declarative structure assembly Make a rune's structural skeleton — the preamble header, the content / media columns, and any other theme-variable grouping — declarative and rune-owned, instead of hand-built imperatively in rune transform TypeScript. SPEC-080 made metadata assembly declarative (metaFields + blocks + layout); this completes the arc by moving the structural skeleton onto the same declarative footing, so a theme can reshape structure without running rune code.Sibling to SPEC-082 (typed node data channel); both extend SPEC-080 and harden the rune output contract before third-party themes depend on its current shape. The two are independent and can land in either order. (This spec was originally drafted alongside the data-channel concern; that half is now SPEC-082.)
5/5 work items
SPEC-082 main
Typed node data channel Replace the <meta data-field> side channel — by which a rune transform passes computed field data to the engine across the serialize boundary — with a typed data bag carried on the serialized node. Extracted from SPEC-081 (Concern B) so it can be planned and sequenced on its own. Sibling to SPEC-081 (declarative structure assembly); both extend SPEC-080 and harden the rune output contract before third-party themes and additional framework renderers depend on its current shape.We start here because it is the channel the whole model rides on, and because it clears the most accreted cruft. It is also lower-risk than it first looks: the engine consumes and strips this channel before any renderer sees the tree (just as it strips <meta data-field> today), so — contrary to an earlier framing — this needs no framework-adapter changes. The fix is confined to the schema, the engine, and the createComponentRenderable helper.
6/7 work items
SPEC-083 main
Semantic chart data and pluggable renderer providers Re-home the chart rune onto the SPEC-081 two-layer boundary: the chart's data is semantic content (the rune transform), and the chart's rendering is pluggable presentation (a web component + a renderer provider) — not a single SVG renderer frozen into the framework-agnostic engine config.
2/3 work items
SPEC-084 main
Rune composability contract Runes are designed to nest — sandbox inside juxtapose, recipe inside preview, a map inside a card media slot. The engine already propagates parent context (parentRune), applies contextModifiers, and cascades childDensity. What's missing is a contract: a declared, validated, and documented statement of how a rune composes — designed so it holds up in an open plugin ecosystem where third parties add runes we know nothing about, and compose with (or inside) ours.
0/6 criteria
5/6 work items
SPEC-085 main
Bento as a composition substrate bento should be a foundational, versatile rune — driving everything from marketing magazine sections to dashboards. Today it is heading-only, a cell has no real structure (only an icon is recognized as a visual; everything else is one undifferentiated body), its sizing vocabulary overlaps confusingly, and it is modelled as a page-section. This spec gives bento a solid foundation by converging the cell onto card's zone contract, a precise sizing model, and two clean authoring front doors — and by reducing bento to a pure grid primitive.
0/8 criteria
4/6 work items
SPEC-086 main
Surface chrome: elevation and frame presets Visual chrome — shadows, crop ratios, bleed/breakout — is currently welded to the showcase wrapper rune. That forces nesting ({% showcase %}…{% /showcase %} around an image) for an effect that is really just styling, and it duplicates attribute combinations every time. tint and bg already solved the analogous problem for colour and background: define a named preset once, apply it via an attribute on any rune. This spec brings the same model to chrome, and resolves the ambiguity that blocks it: when a rune (like card) hosts media, which surface does a given chrome attribute decorate?
0/13 criteria
4/5 work items
SPEC-087 main
Surface fills: substrate patterns and tint-tracked inset surfaces SPEC-086 gave a surface its chrome — shadow (elevation) and media presentation (frame). A surface also has a fill. Today two fill primitives exist — tint (a colour-token bridge) and bg (an image/video layer) — but there is no way to print a generated pattern/texture (dots, grid) on a surface, no recessed inset fill that tracks the surface colour, and no way to scope a fill to a rune's inner media well versus its whole surface. This spec adds substrate (the pattern layer) and a derived inset surface, and defines how surface fills target the self surface vs an addressable media well — the missing fill column of the surface model.
0/10 criteria
3/3 work items
SPEC-088 main
bg gradients and a formalized custom-CSS escape hatch bg is the deepest layer of the surface model (SPEC-087) — the image/generated-image fill beneath tint (colour) and substrate (pattern). Today it handles image/video/overlay layers plus a theme-level backgrounds preset registry, but it has two gaps and one incidental wart:
0/9 criteria
4/4 work items
SPEC-089 main
Cover layout for media+content runes: media-position="cover", content placement, and intrinsic height A media+content rune (card, bento-cell, recipe, …) normally lays its media and content in separate, non-overlapping tracks — media-position="top|bottom|start|end". This spec adds a cover layout mode where the media fills the rune's interior and the content overlays it — the poster / cover card — preserving the thin-edge frame and media radius, with a content-placement control, a default legibility scrim, and an intrinsic-height answer for both cover and bg-only cards. It was battle-tested against a profile-card example (a normal media-top card vs the same card with the media pulled down to cover, text overlaid).
0/12 criteria
4/4 work items
SPEC-090 main
Media-guest interaction posture: presentational guests, clickable containers, cover backdrops A media-slot guest can be interactive (a codegroup's tabs, a live pannable map, a form, a sandbox) and its container can also be an interaction target — a card or bento-cell with href, rendered as a stretched whole-tile link. Today these collide with undefined behaviour: the link is a stretched overlay (.rf-bento-cell__link { position:absolute; inset:0; z-index:0 }) and only a:not(.link) is lifted above it (z-index:1), so a guest's buttons sit under the link and their clicks are mostly eaten — the tabs look clickable but aren't. Layering an interaction target over interactive controls is also the classic nested-interactive-in-a-link accessibility antipattern (ambiguous focus and activation). This isn't a style preference; the model has to pick a defined posture.
0/6 criteria
3/3 work items
SPEC-091 main
Engine config variants: modifier-keyed config deltas The rune transform was deliberately reduced to flat, semantic output — it decides what each Markdown primitive means (a paragraph before a heading → eyebrow, an unordered list → ingredients), and nothing else. Structure is the engine's job (the SPEC-081 declarative layout assembly from flat slots); style is CSS's. But some runes need their structure to vary by a modifier:
0/9 criteria
4/4 work items
SPEC-092 main
Frontmatter-declared registry entities Let content pages contribute to the entity registry through their frontmatter: index arbitrary frontmatter fields onto the page entity, and let a page declare a first-class registry type so collection / aggregate can query it. The catalogue is open-world — assembled from pages that self-declare, not from a code catalogue. Realises ADR-016; builds on the SPEC-070 query grammar and complements SPEC-069 (entityRoutes, the inverse mapping).Target: next minor (post-v0.20.1).
0/6 criteria
2/2 work items
SPEC-093 main
Data-bound sandbox Let a sandbox be fed data from the registry: bind a query, resolve it at build time, and inject the JSON result into the iframe so author code (three.js, d3, canvas — anything) can render it. The registry's third render target after collection (HTML) and aggregate/chart (SVG): bring your own renderer. Realises ADR-017; builds on the SPEC-070 query grammar, pairs with SPEC-092 (richer queryable entities) and SPEC-072 (relationship edges).Target: v0.21.0.
0/5 criteria
3/3 work items
SPEC-096 main
Editor registry awareness The block editor predates the registry era. The registry-query runes (collection / relationships / aggregate, v0.16.0) and frontmatter-declared entities (SPEC-092) turned the entity registry into a core authoring primitive — but the editor treats cross-page data as an afterthought: a snapshot cached at startup, no query assistance, no entity fields in the frontmatter UI, and registry runes that render as empty shells in block mode. This spec makes the registry a first-class citizen of the editing experience.Target: an editor-focused minor after the foundations land (WORK-056, WORK-393).
0/6 criteria
0/1 work items
SPEC-097 main
Editor config studio refrakt.config.json has grown from a content pointer into the project's control panel — multi-site sites, a structured theme object (package, presets, per-mode token overrides, code colour scheme), named tints and backgrounds, inline-SVG icons, plugins, routeRules, entityRoutes, plus root-level plan, xrefs, and fileRoots. The editor reads and writes exactly one of these fields (routeRules), and even that has no UI. This spec gives the editor a Site Settings area with proper UX knobs for the config surface, with a raw-JSON escape hatch so the UI never blocks access to new fields.Target: editor-focused minors; panels are independently shippable.
0/8 criteria
SPEC-098 main
Editor appearance panel and attribute UX The surface-model wave (SPEC-086 frame chrome, SPEC-087 substrate fills, SPEC-088 bg gradients + scrim, SPEC-089 cover layout, SPEC-090 guest posture) added ~35 universal attributes to every content-model rune. The editor's attribute UI predates all of it: a flat list with no grouping, no enum widgets, no conditional applicability, and none of the engine's soft-lints surfaced while authoring. This spec replaces the flat list with a grouped, progressively disclosed Appearance panel and makes attribute editing vocabulary-aware.Target: editor-focused minor; depends on WORK-395 for the warning channel.
0/6 criteria
SPEC-099 main
Feature rune layout axis and responsive collapse Give the feature rune an honest layout axis (grid | list, drawn from the ADR-018 canonical pool) for arranging its feature-items, retire the implicit coupling that infers the grid from media-position, and define how the item arrangement collapses responsively. Carousel is explicitly out of scope here — it lands in SPEC-100 once the shared contract exists.Target: next minor.
0/9 criteria
SPEC-100 main
Carousel as a shared layout mode Promote carousel from a gallery-coupled behavior to a canonical layout mode (ADR-018) that any rune can opt into via layout="carousel". Generalise gallery's carousel into a block-agnostic, contract-bound behavior; define the shared track/item DOM contract behind the carousel token; then adopt it across the candidate runes, starting with feature.Target: next minor (after SPEC-099).
0/8 criteria
SPEC-103 main
data rune — external tabular sources A preprocess-time rune that reads an external tabular source (CSV, JSON, NDJSON; SQLite later) and emits a Markdoc table AST node. Because chart (SPEC-083) and datatable both already treat an authored <table> as their single source of truth, a table-emitting data rune feeds both — plus the bare page — with zero changes to either host rune. It is the external-source sibling of SPEC-062 (snippet, which emits a fence) and the external-source complement to aggregate/SPEC-093 (which project the internal registry).Target: next minor (post-v0.21.0).
0/8 criteria
0/1 work items
SPEC-104 main
Live sandbox guests in the bg backdrop layer bg (SPEC-088) can fill its backdrop with an image, video, or gradient — resources fully specified by a URL or token reference. It cannot host a live program (a three.js / canvas visualizer in a sandbox). This spec adds a bg guest: a sandbox rendered into the bg layer as a bare, presentational, full-bleed backdrop — behind a rune's content, beneath its tint/substrate, never in flow. It also adds a named, transform-resolved sandbox preset so a reusable backdrop is applied by name (bg="midnight-waves") like any other preset.This is the missing layer that lets a surface carry both an animated backdrop and a positioned subject media: the visualizer is the bg, the image/video is the in-flow media guest. It is the general fix behind the music-blog hero (a playlist whose cover is a live audio visualizer with a mood image), but it is a surface-model capability, not a media-specific one.Target: next minor.
0/7 criteria
0/3 work items
SPEC-105 main
Scroll-reveal motion — a token-driven entrance dimension refrakt can compose elaborate backdrops (bg, substrate, cover) but has no vocabulary for choreography — how a section arrives. Add a motion dimension: a small, closed, author-facing reveal vocabulary that declares the intent of an entrance (a section fades in; feature items slide in as they scroll into view), with the theme owning the choreography and an IntersectionObserver behaviour owning the timing trigger. Motion is opt-in, token-driven, and enhancement-gated so the static page is always complete.Target: next minor.
0/9 criteria
0/4 work items
SPEC-106 main
Image-src scheme sugar: placeholder: and icon: Standard Markdown image syntax with a custom URL scheme in the destination — ,  — resolved during the transform into generated inline SVG. Two long-wanted affordances fall out of one small mechanism: a generated image placeholder for drafts/fixtures, and the icon: sugar for the icon rune that was discussed when the icon rune landed but never built.
0/6 criteria
5/5 work items
SPEC-108 main
Reading role: an editorial treatment for body text Builds the reserved candidate from SPEC-094 §8 — a prose/reading classification for body content. Every theme axis to date (elevation, prominence, width, density, tint, frame) governs a rune's container; none touch how the running text inside reads. For the magazine / editorial / business themes the SPEC-094 epic targets, the reading treatment of body copy — measure, paragraph rhythm, drop-cap, the styled opening — is arguably the single largest differentiator between a product/docs theme and an editorial one, and today there is no attribute to hang it on.
0/6 criteria
Review 4
SPEC-004 main
Layout System — Specification Standardised layout attributes for grid and section runes, page-level breakout, showcase effects, background media Tint Rune Specification, Community Runes Specification, Vite Plugin Specification
SPEC-008 main
Unbuilt Runes — High-Level Spec Runes listed in plan/spec/community-runes.md that do not yet have schemas in packages/runes/src/tags/
2/6 criteria
0/13 work items
SPEC-015 main
Plan Site UX at Scale Future UX improvements for the plan site to handle large projects with many work items, specs, bugs, and decisions.
SPEC-028 main
Rune Output Standards Codify the structural patterns established by the recipe rune as the reference standard for all rune output — schema transforms, engine configs, and identity-transformed HTML.
Accepted 29
SPEC-001 main
Community Runes — Specification Package system, namespacing, rune extension, ecosystem architecture
0/4 work items
SPEC-002 main
Cross-Page Pipeline — Specification Build pipeline phases, entity registry, content aggregation, post-processing hooks Community Runes Specification, Storytelling Runes Specification
0/4 work items
SPEC-003 main
Declarative Content Model — Specification Schema-driven content parsing that replaces per-rune processChildren methods Alignment Specification, Media Runes Specification, Layout Specification
SPEC-006 main
Media Runes — Specification Playlist, track, and audio rune content models, compact format, and player integration Related: Unbuilt Runes Spec, Sandbox Futures (audio visualisation synergy)
SPEC-009 main
Rune Editor Compatibility Spec This spec covers all remaining runes that need updates for editor compatibility. Three runes have already been updated: recipe, hero, and feature. This document covers everything else.
137/137 criteria
0/1 work items
SPEC-012 main
Rune Inspector — Transformation Pipeline Debugger for VS Code @refrakt-md/vscode, @refrakt-md/language-server
SPEC-014 main
Plan Site via HTML Adapter Refactor plan serve and plan build to render through @refrakt-md/html instead of a bespoke HTML pipeline, and introduce a planLayout in the transform layer.
SPEC-021 main
Plan Runes Runes for spec-driven project management in AI-native development workflows. Package: @refrakt/plan.
0/5 criteria
1/1 work items
SPEC-022 main
Plan CLI Plan management subcommands for the refrakt CLI. Package: @refrakt-md/plan.
0/4 criteria
SPEC-024 main
Metadata System Semantic metadata attributes on structure entries for consistent cross-rune badge styling. Extends the existing StructureEntry interface with three dimensions — type, sentiment, and rank — so themes can style every metadata badge generically.
SPEC-025 main
Universal Theming Dimensions Cross-rune semantic data attributes — surface, density, section anatomy, interactive state, media slots, checklist, and sequential items — so themes can style every rune generically with ~54 CSS rules instead of per-rune overrides. Builds on the metadata system (SPEC-024) to complete the ten-dimension universal theming model.
SPEC-026 main
Lumina Theme — Reference Implementation Lumina is the default theme and reference implementation of the universal theming dimensions (SPEC-024, SPEC-025). This spec documents Lumina's concrete choices for surface assignments, sentiment colours, density behaviour, media sizing, and per-rune overrides — proving the dimension model works end-to-end and serving as the template for community themes.
0/9 criteria
SPEC-027 main
Work Item Resolution Summaries When a work item or bug is completed, append a structured Resolution section capturing what was done, linking to branches/PRs, and recording implementation notes. Designed for agent workflows where the completing agent's context is lost after the session ends.
SPEC-030 main
Framework Adapter System Extend refrakt beyond SvelteKit to support Astro, Next.js, Eleventy, and Nuxt — four framework adapters built on the existing framework-agnostic core. This spec defines the shared prerequisites, per-adapter scope, and phased delivery plan derived from ADR-001 (Astro readiness) and ADR-002 (Next.js, Eleventy, Nuxt readiness).
0/1 work items
SPEC-032 main
Remove Legacy Model Class and Decorators Migrate all runes from the imperative Model + decorator pattern to createContentModelSchema, then remove the legacy API surface entirely.
SPEC-033 main
Structure Slots and Declarative Flexibility Extend the identity transform's StructureEntry system with named slots, ordered placement, value mapping, repeated element generation, and element projection — giving theme developers structural creative freedom without resorting to postTransform.
0/2 work items
SPEC-037 main
Plan Package Hardening Fix bugs, close validation gaps, implement knownSections for plan runes, and add missing CLI capabilities — all before building the Claude Code plugin layer (SPEC-036).
SPEC-040 main
Edge Runtime Compatibility for Plan Package Refactor @refrakt-md/plan so that its pure logic — parsing, diffing, filtering, relationship building, entity card construction — can be imported in edge runtimes (Cloudflare Workers, Deno Deploy, Vercel Edge Functions) without pulling in Node.js APIs (node:fs, node:child_process, node:path).
SPEC-041 main
Agent Rune Reference A CLI surface that lets a coding agent (Claude Code, Cursor, Copilot, etc.) discover the input syntax of any installed rune — tag name, attributes, content interpretation, and a minimal example — without invoking an LLM.
SPEC-048 main
Design tokens contract & config Promote refrakt's design tokens from an implicit set of CSS custom properties owned by Lumina into a typed, theme-agnostic contract — so any theme can supply values for the same names, sites can override tokens declaratively in refrakt.config.json, presets become shareable data, dark mode is part of the same surface (not a separate CSS file), and the syntax-highlighting surface stops leaking the underlying highlighter (--shiki-* → --rf-syntax-*).
0/40 criteria
SPEC-054 main
Nav: richer dropdowns and column flow Evolve the existing nav layouts so authors can compose Linear- / Vercel- / Stripe-style header dropdowns out of the primitives they already know. Three coordinated changes: (1) layout="menubar" accepts arbitrary block content inside ## groups — including nested navs, paragraphs, blockquotes, and images — with a position-based slot rule (first content block = intro, last = footer); (2) layout="columns" gains a ----between-sections column-break rule and a headingless mode, so it can serve both as a footer-columns nav and as the inner content of a menubar panel; (3) a new layout="strip" for compact secondary link rows, useful both standalone (persistent sub-nav) and nested inside a panel footer slot. Plus a new core {% badge %} inline rune and a generalisation of auto=true description/icon enrichment to every layout.
0/39 criteria
SPEC-055 main
Nav slug resolution and active state Disambiguate nav item slugs that match multiple pages, and fix the related symptom where multiple nav items render as active simultaneously. Introduces multi-segment slugs as the first-class disambiguator, nav-location-relative resolution as the default, hard build errors on unresolvable bare slugs, and a longest-prefix-match active-state rule with aria-current="page" plus data-active="ancestor" semantics.
0/17 criteria
SPEC-078 main
file-ref rune + shared preview attribute on reference runes A path-based reference rune (file-ref) that points at a project file from prose with an auto-resolved GitHub URL, plus a shared preview="…" attribute on both file-ref and the existing xref rune that hoists a drawer (or future popover / details / sidenote) containing the referenced content — the common case for "preview a file or entity behind a link." Adds a footer slot to the drawer rune for the canonical "View source on GitHub →" / "View full page" link, plus an always-visible flex-column chrome so the footer stays one tap away regardless of body scroll depth.
0/17 criteria
SPEC-094 main
Theme system foundations for multi-theme development Lumina is the only theme refrakt ships, and several things "work" only because there is exactly one of them. Lumina is tuned for a specific brief — project landing pages plus Tailwind/Linear-style docs. The next themes target a different audience entirely: magazines, editorial blogs, and businesses. Two requirements pull against the current design: a new theme must be quick to build (the workflow is AI-assisted), and it must be able to look unmistakably unlike Lumina.The transform/dimension architecture is sound — the identity transform emits semantic data attributes (data-meta-type, data-section, data-density, data-media, …) and a theme styles them generically, covering the bulk of runes without per-rune CSS. The override and cascade machinery is also strong: a typed SPEC-048 token contract, site-level theme.tokens/modes, presets that merge as ThemeTokensConfig, a four-level tint cascade, and FOUC-safe dark mode. CSS swapping is already wired — the SvelteKit Vite plugin routes a theme's CSS through virtual modules, so pointing site.theme.package at a different package rewires the import chain automatically.What is missing is not plumbing but differentiation surface and anti-duplication wiring. This spec defines the foundations that must land before theme #2, so that a new theme is largely a token file plus a layout plus targeted surface CSS rather than a fork of 13.6k lines of Lumina CSS.
0/13 criteria
11/15 work items
SPEC-101 main
Hero cover layout — animated sandbox backgrounds hero grammatically accepts media-position="cover" today (it's in the shared splitLayoutAttributes), but the combination has never been exercised: no docs example, no CSS pass, no contract coverage. Meanwhile the pieces for the obvious payoff — a live three.js scene as a full-bleed animated hero background — already exist separately: cover layout (SPEC-089), sandbox as a media guest (WORK-382), and the interaction-posture contract that demotes a cover guest to an inert presentational backdrop (SPEC-090). This spec closes the gap: make hero a first-class cover host, make non-img/video media guests (specifically sandbox) fill the cover well, and ship the animated-background composition as a documented, tested pattern.
0/11 criteria
5/5 work items
SPEC-102 main
Standardised rune example fixtures Every rune carries example content — a small Markdoc snippet showing the rune in use. That content is quietly load-bearing: it feeds refrakt inspect, the block editor's insert-example, the docs/reference builder, plugin-validate's coverage check, and — once SPEC-094 lands — the kitchen-sink gallery and its visual-regression harness. It is also the obvious corpus for the AI content generator.But that content lives in four places with no shared format:
0/7 criteria
5/5 work items
SPEC-107 main
Elevation, prominence & the surface-axis decomposition An amendment to SPEC-094 §8 ("Surface as engine-emitted config"). §8 established that the surface dimension (card | banner | inline | inset) is the lone holdout that still falls back to rune-name selector lists in surfaces.css, and resolved to emit it from engine config as data-surface. This spec keeps that goal — kill the static rune-name lists, make the rune→treatment assignment theme-overridable config — but revises what the axes are. It decomposes the single "surface" enum into orthogonal axes, gives the chrome axis an ordered depth vocabulary, and adds a prominence axis that §8 explicitly deferred. The motivating use case: the same recipe should read as a bordered card mid-prose and as a full-bleed, large-title hero at the top of a page — without forking the rune.
0/8 criteria
5/5 work items
Superseded 0
Deprecated 0