Project/Changelog
Every line, evidenced.
Published, candidate, withdrawn and historical release evidence for OpenElement.
The currently published package line isv0.44.0-beta.1.
The project follows Keep a Changelog and SemVer. Historical entries preserve older names where they describe older releases; current docs use the openElement contract.
The published five-package line — unified product and website surface, sealed export seams.
The eleven-package era — JSR-only, before the collapse. Historical record.
Stable line
v0.43.3is the published stable maintenance baseline on the 0.43 track. The static, request-time, and Universal WC SSR contracts remain frozen under ADR-0119, ADR-0122, and ADR-0135; ADR-0140 admits compatible bug, security, runtime, documentation, and release-truth patches without scheduling a 0.44 feature train.
Withdrawn partial artifacts
The npm beta.1–beta.3 artifacts are withdrawn partial releases, not supported product lines or upgrade targets.
※ Withdrawn partial artifacts (beta.1–beta.3) stay withdrawn from the active release story. History is kept, not rewritten.
Historical archive. The maintained, per-release record lives in
docs/release/and is the authoritative source. This file is an aggregated history only: it is not re-synchronized release by release and there is no mechanism keeping it in lockstep withdocs/release/. When the two disagree,docs/release/wins.
Current truth lives in:
docs/current/VERSION_PLAN.mddocs/current/PACKAGE_SURFACE.mddocs/status/STATUS.mddocs/roadmap/ROADMAP.md
Historical changelog details remain available through git history and release evidence.
0.42.0
WC light fullstack, stable. The stable cut of the 0.42 alpha line — the
request-time Application Loop (ADR-0120) frozen on top of the untouched
0.41.x static freeze (ADR-0119), with freeze scope and non-goals in ADR-0122
(accepted 2026-08-14, TP-6). See the per-alpha entries below for the full
train history; docs/release/v0.42.0.md is the authoritative note and
docs/release/v0.42.0-migration.md the upgrade guide.
- Frozen scope (ADR-0122 §1–§4): the loop contract (loader/action
signatures,
fail()/redirect()algebra + HTTP encodings, PRG revalidation, no-JS baseline), the action protocol (x-openelement-action, morph client contract, channel symmetry), the fail-closed CSRF same-origin default, and first-mile start semantics. Breaking changes to these require an amendment ADR. - Breaking changes since 0.41.x:
IslandOptions.strategyrenamed tohydratewith no alias (ADR-0127); shape-1 SSR markup gains one fallback-tag wrapper element (#960, ADR-0128); head-injection tightening —<base>/<meta http-equiv>/ raw<script>rejected inheadExtras(#931); unfrozen alpha exports removed (i18nStaticPaths,switchLocale,AppIslandOptions,OPEN_PROPS_TOKEN_CSS, theOpenElementRouteNodere-export); pure-static builds no longer emitdist/server/(#953); minimum Deno version is 2.8 (the generateddist/serverrequires Node ≥ 20.19 or Node 24 — the stale Node 18+ claim is tracked as #969). - Upgrade: pure-static and SPA projects need zero source changes — bump
the five
@openelement/*specifiers to0.42.0, refresh the lockfile, rebuild (byte-level upgrade proof in the release note). - Not frozen / not claimed: session/flash, cache/ISR (
revalidatestays inert forward-compat data), streaming SSR, performance SLOs, third-party WC SSR corpus (0.43), production runtime recovery (0.44).
0.42.0-alpha.17
Registration-decoupling train (#960, ADR-0128) plus the architect final review's hardening and documentation set.
- Breaking (SSR markup, ADR-0128): route modules whose default export is
definePage(...)now register the page class under the route-path-derived fallback tag (app/routes/index.tsx→index-page); theexport const tagNameon a definePage route is ignored for registration and only names a content element (#960). Shape-1 pages (starter pattern) gain the fallback-tag page element as an outer DSD wrapper around the content element; hydration markers and morph behavior are unchanged, but user CSS targeting the old root tag must target the new fallback tag or the content element. Plain element routes (no definePage) keep theirtagNameexport as the registration tag. Fixes the silent loss of the definePage render when a module self-registered a content element under the same tag. Migration:docs/release/v0.42.0-migration.md.
0.42.0-alpha.16
Starter-first remediation train (issues #915–#959): the remaining headline gaps from the round-3 audit close, with e2e gates pinning each fix.
- Island runtime:
hydrate: 'only'islands now bind events and signals instead of rendering inert (#939); function-modedefineIslandislands re-render on signal change (#940). - Routing/SSR semantics:
notFound()from a page render propagates to a real 404 status (#922); unmatched request-time paths render the styled 404 page withCache-Control: no-store(#923). Successful GET pages relax fromno-storetoprivate, no-cacheso the UA can restore scroll position and use bfcache (#943); POST responses keepno-store. - element runtime:
<style>/<script>text children serialize as raw text — CSS selectors with>no longer corrupt (#932);data:URIs are allowed onimg srconly, nothref(#929); keyedForsemantics locked (a data change without a key change does not re-render, #915), its AbortSignal teardown leak fixed (#916), and the coverage matrix landed (#918). - Breaking (unfrozen alpha surface): head-injection sanitization is
tightened —
<base>and<meta http-equiv=...>are now stripped fromheadExtras/head fragments (#931). Apps injecting a CSP meta or base tag throughheadExtrasmust move those into the document shell / SSG postprocess directly. - Breaking (alpha surface, ADR-0127): element's
IslandOptions.strategyis renamed tohydrate(#920), matching the app-sidedefineIslandConfig({ hydrate })name; the old name is deleted with no alias. Migration: renamestrategy→hydrateat each elementdefineIsland()call site. App-side authoring is unaffected. - Starter surface: the dev task pins the same vite version as the import
map (#927); the template ships working blog routes (
content/blog,@openelement/generated/blog-data, styled 404app/routes/404.tsx) — a copyable example for the documented virtual module and the shadow-DOM styling constraint. - CSRF and enhanced forms: request-time mutation endpoints enforce a
coherent Origin policy matrix — cross-site POSTs are rejected while
same-origin native form posts (
Origin: null+Sec-Fetch-Site: same-origin) pass (#921, #938); enhanced forms morph correctly into slotted light-DOM pages (#937). - keyed For hydration: matched DSD hydration keeps keyed
Forlists reactive — per-item boundary markers pair hydrated list groups with theirFortarget by branch ordinal (#917). - ErrorBoundary: render failures inside a subtree are auto-captured by
the nearest
ErrorBoundary(ADR-0053 Layer 2) and bubble outward when a fallback itself throws (#919); a subclassrender()must branch onhasError(#958). - Pre-hydration clicks: clicks landing between first paint and island
hydration are captured and replayed once when the island hydrates (#942).
Capture starts when the generated client entry executes — clicks that
land before the client script loads are still lost; replayed events carry
isTrusted=falseand native default actions (anchors, checkboxes) may run twice. - Dev chain: dev serves the island client entry and injects its script tag (#951); dev SSR re-definition overwrites stale classes in the customElements stub (#952).
- Build output: pure-static dist drops the build-time SSR bundle
(#953);
.mdxroute files are discovered and rendered (#954); index routes keep clean URLs when a same-named sibling directory exists (#956); request-time builds emit a standalonedist/server/serve.mjsentry (#959); thecorsOriginmisconfiguration warning is emitted once per process (#925). - Docs: minimum Deno version declared and the markdown post-title H1 rule documented (#928, #935).
- Further fixes in this train: unserializable island props degrade like
a
render()failure instead of crashing SSR; the depth-limit error is logged once, not once per bubbled frame; the standaloneserve.mjsvalidatesPORT/OPEN_ELEMENT_PORT; the dev island client entry matches URLs with query strings; the missing-tagNamescanner note is silenced for definePage routes; the SSR instantiate-failure fallback now preserves attributes like the render-failure fallback (#892 partial);target="_blank"case variants get a forcednoopener; CSS escapes/comments are folded before the style blocklist check; event-binding disposers register under signal lifecycles; keyedForrewinds its insertion cursor on duplicate-key displacement.
0.42.0-alpha.15
Backlog-zero train: built-in HTML sanitization and keyed reconciliation land in the element runtime, alongside a wide simplification sweep.
- element runtime: built-in allow-list HTML sanitizer
sanitizeHtml(#894); keyed<For each key>reconciliation via an optionalkeyprop (ADR-0124, #890), with displaced entries disposed on duplicate keys (#911);isSafeUrldecodes:and_blanklinks getrel=openerneutralized (#911); guardedRenderHooksthrow semantics documented (#911); the DSD layout-fix flush is chunked across frames (#896); SSR/CSR prop collection unified and theOpenElementbase class split into collaborators (#903, #904, #906, #900). - Correctness: SPA router gains a URLPattern fallback for Firefox
(#897); framework throws converge on
OpenElementError(#898, #899). - Docs truth: code-claim registry with a claims gate wired into
docs:truthand the AutoFlow gates (#893, #911). - Hygiene: simplification sweep across tools/packages/www (dead exports,
release.tssplit, Web/ES/Deno std API convergence, unused import-map entries dropped); e2e made network-independent viahost-resolver-rules.
0.42.0-alpha.14
Simplification and consumer-packaging train: the packed-package consumer path is unblocked and dead surface is swept repo-wide.
- Consumer packaging: packed-package consumers of jsr dependencies
unblocked and the consumer smoke fixed (#886, #887); client runtimes are
bundled via virtual modules instead of
toString()(#868); jsonc parsing delegated to@std/jsonc(#870). - Release tooling: no-skip version continuity and pre-seeded release note survival (#869, #855); docs-truth five-in-one registry and consumer qualify tiers (#870).
- Hygiene: simplify-scan deletion rounds swept dead files, dead exports and dead flags (#879–#884); architecture anti-rot quirks ledger (#871).
0.42.0-alpha.13
Standards-as-seams train + TP-6 freeze preparation (16 issues: #603–#610, #856–#860, #863–#867; ADR-0123).
- Morph robustness (the alpha.7 debt, all of it): the enhance/island
client is a real tested module instead of a 400-line string template
(#610); focus, scroll and form-control state survive enhanced updates
(#603); nested DSD templates instantiate recursively (#604);
open:readyfires for every strategy bucket (#605); island scheduling has a single owner (#606). - Route standards: all route matching is WHATWG URLPattern — the SPA
client router and the generated server matcher share one semantics (#856);
renderIntent.modeis honestly'static' | 'dynamic'with the'auto'alias removed (#609). - Server seams: a WinterCG-shaped fetch middleware contract runs
identically in dev,
start, fixtures and Nitro (#858); nitro-mount is a near pass-through on Nitro v3's nativeRequest(#857);cli/previewmerged intocli/start --mode=preview(#859). - Protocol: fetch-channel error responses are RFC 9457
application/problem+json, including the CSRF 403 (#863). - Components:
open-inputbecomes a real native-form citizen (ElementInternals pilot, #864);open-dropdownmoves to the Popover API with CSS anchor positioning (#865). - Site search: full-text, ranked, bilingual via Pagefind (#867).
- TP-6 preparation: migration note, zero-cost upgrade proof and ETag revalidation design note (#866).
0.42.0-alpha.12
Round-6 full-spectrum audit remediation train: all 112 findings from the
2026-08-02 round-6 audit (issues #810–#852) are fixed; the report lives at
docs/audit/2026-08-02-round6-audit.md.
- Correctness: a guard-vetoed
redirect()from a post-action loader re-run no longer wipes page data — the action path mirrors the #802 navigation guard (#810); the SPA client router matches Hono-style:param{.+}catch-all patterns (#812); malformed percent-encoded URLs are a defined 400 instead of a hung request (#823). - CSRF floor proven: the generated action POST same-origin floor has
real deny/allow e2e coverage, with
OPEN_ELEMENT_DISABLE_CSRF=1as the documented opt-out (#811). - Honest claims: ISR labelled forward-compat/inert wherever it appears
(#840, #842, #843); the security guide documents the built-in CSRF floor
(#815); the starter
headerNavconfig actually renders (#829). - Gates that gate:
verify-package-configsperforms a real version check (#824);stripCommentsis string-literal aware (#826); mojibake and stale-claim pattern lists single-sourced (#827, #838); the five-package roster derived from one constant (#828). - Hygiene: 23 dead SVG icons deleted (#831); the dead blue/teal/cyan
token palette no longer ships in every page (#832);
data-ssr-propssingle-sourced (additiveDATA_SSR_PROPSexport, #836); dead exports and config swept across all five packages (#833, #834, #845–#852).
0.42.0-alpha.11
Round-5 full-spectrum audit remediation train: all 78 findings from the
2026-08-01 round-5 audit (issues #730–#809) are fixed; the report lives at
docs/audit/2026-08-01-round5-audit.md.
- Security:
validateSafeUrltab/newline bypass closed (module-scriptdata:XSS, #761); desktop examples bind loopback only — the reader's LAN-reachable arbitrary file read and remote kill are gone (#777); Mastodon example no longer caches API errors as data (#775). - Correctness: a guard-vetoed redirect during navigation keeps the
current page's loader data (#802);
useLoaderData<T>()honestly typesT | undefined(#763); theme broadcast no longer clobbers host-owneddata-theme(#773); disconnect→reconnect no longer resets non-reflected prop state (#772); JSX callbackrefis consumed (#756);open-buttonanchor-mode disabled sync works both ways (#757);open-input/open-badgeobserve dynamic attribute changes (#769, #770); blog locale fallback direction fixed (#759); three empty-shell site-ui components registered (#758); page-rail scroll-spy active state applies (#779). - Honesty over surface: the homepage flagship example is real compilable API (#762); dead options, dead config keys and misleading types removed across element/app/adapter-vite (#764–#768, #771).
- Repo hygiene:
.githooksexecutable again so local gates cannot be silently skipped (#760); duplicated tools helpers single-sourced; ~40 dead exports / dead files swept.
0.42.0-alpha.10
- Cleanup and hardening train (milestone #17, 97/97 issues closed): the evidence-chain batch (#646–#653), the P1 correctness batch, the P2 batch and the P3/P4 hygiene sweep land together. No new product surface; the ADR-0119 freeze surface and the ADR-0120 Application Loop scope are untouched.
- Release tooling: two-stage publish now requires a durable, gated prepare
record — publish-existing refuses to run without one (#684, closes the
alpha.8 version-hole class); the docs stale guard is parameterized off
PREVIOUS_PACKAGE_VERSIONso the next bump cannot self-collide (#727);bump-version.tsdocuments its half-bump role (#687); the dead JSR publish channel is removed (#746). - Runtime correctness: element
update()routes re-render errors toonRenderError(#662); SPA loader failures take the__openElementErrorchannel (#676) and SPA loader/action honorredirect()/notFound()with real navigation (#731); ui double-escaping removed (#726), open-tabs accessibility rewrite (#666) and instance-unique ARIA ids (#745), open-dialog SSRopensync (#667); generated-data writes fail closed in build mode (#671);getStaticPathserrors honordynamicRouteFailure: 'fail'(#672); the start CLI static server is shared with the CI fixture and its request-time response unwrap is fixed (#732);adapter-vitedeclares itstypescriptdependency so published consumers resolve (#725). - Hygiene: element's three internal barrels collapse to one (#739); the dead
internal/content/mdx/directory, protocol seam shells, codegen dead re-exports and the JSR machinery are deleted (#694/#697/#741/#746); zero-consumer exports dropped across app/element/ui (#740/#743/#747); www guide pages share one shell and dead islands/icons/blog content are removed (#749/#748); audit reports archive underdocs/audit/with the citation guard rescanning them (#751). - Breaking (unfrozen alpha surface, per PACKAGE_SURFACE.md):
@openelement/appdropsi18nStaticPaths/switchLocale/AppIslandOptionsand theOpenElementRouteNodere-export from./model(#743);@openelement/ui/open-props-tokensno longer exportsOPEN_PROPS_TOKEN_CSS(#747); the generated ui manifest corrects open-tabs slots to['tab','panel'](#744).@openelement/elementgains@experimentalexports: ISR cache types (#729) and the third-party client runtimehydrateOpenElement/disposeOpenElement(#740). - Docs truth: the npm registry line and the source line are now stated as two
lines everywhere (README/ROADMAP/WORKFLOW/www), and the version-anchor and
www-truth gates enforce the dual-line form (#730);
docs/integrations/is covered by a package-surface truth gate (#737); the Fresh guide is rewritten against the real example (#728); the ISR KV adapter contract samples compile (#729).
0.42.0-alpha.9
- Cleanup train (TP-5.7, milestone #16): 13 findings from the 2026-07-30 team cross-review (issues #632–#644) landed as a quality/hygiene drop. No new product surface; ADR-0119 freeze surface and 0.42 Application Loop scope (ADR-0120) are untouched.
- Correctness:
<open-button>now binds_handleClickas an arrow-field so the framework's rawaddEventListenerwiresthisto the component instance — shadow-DOM submit events now reach the outer form (#637). Request-scoped context is passed explicitly through render/hydrate entry points (#632/#644); logger_warnedmoved to render scope (#643);appreuses@openelement/element'screateLogger(#636). - Hygiene: removed the redundant
appre-export layer (#634); dropped a dead router data-context module; trimmed unused exports acrosspackages/*(#633/#635/#642/#643/#644). - Release evidence: closure recorded at the tagged merge commit; all five packages
(
@openelement/element,app,adapter-vite,ui,create) are published to npm withdist-tag alpha=0.42.0-alpha.9.
0.42.0-alpha.8
- Incomplete release (npm-unpublished).
v0.42.0-alpha.8was cut as a mechanical version bump with a git tag and GitHub release, but the npm publish step failed and the packages were never published. It is a version hole:git tag v0.42.0-alpha.8and the GitHub release exist, but@openelement/*@0.42.0-alpha.8is absent from the registry and no AutoFlow3 closure was written. - Immediately superseded by
0.42.0-alpha.9, the first fully npm-published0.42.0prerelease. Retained as-is perdocs/release/v0.42.0-alpha.8.md(no closure by design). See that note for the post-mortem.
0.42.0-alpha.7
- Patch release (publish-existing):
0.42.0-alpha.6→0.42.0-alpha.7, statuscompleted. All five packages published to npm withdist-tag alpha; a full AutoFlow3 evidence chain was recorded (verify source version → main CI → artifact gate → publish npm → verify npm versions/dist-tags → consumer smoke → third-party Web Component smoke → stage/commit evidence → tag → push → GitHub release). - Tag commit
e0e46281; publish run30431305870./@fs/Windows verification status tracked indocs/current/HYDRATION_CONTRACT.md(Known limitations).
0.42.0-alpha.6
- Audit round 2 remediation (TP-5.6): the second, independent review of
the application loop
(
docs/audit/2026-07-28-alpha5-round2-review.md, issues #576–#593) is closed — five high-severity defects in the morph client plus the protocol and evidence tail. - Morph client correctness: an explicit
<form action>now wins over the page URL on enhanced submits (#576); the popstate guard survives reloads and bfcache restores (#578); morphed-in islands show the server render (manual DSD instantiation before insertion, #579); morph matching is an ordered walk with exact deletion and relocation — reordered id-keyed lists keep order AND island state (#580); nested DSD compares normalized on both sides (#582); forms inside late-hydrating islands get the enhancement listener (#584); a cancelableopen:action-errorhook precedes the network-failure reload (#585); morph fallbacks log a reason in dev (#589). - Detection:
hasEnhancedFormsfollows relative imports, so an enhanced form inside a shared component no longer loses the enhancement layer silently (#577). - Protocol tail: malformed form bodies answer 400 on both channels (#581); the redirect duck type honors the 3xx whitelist (#583); 405 responses carry no-store/Vary (#586).
- Evidence: parity contract extended to JSON 404 / contract-violation 500 / malformed-body 400 / 405 / the 303→GET chain (#587); local playwright retries are zero (#590); the alpha.2 note gets the enhancement-inert erratum (#591).
0.42.0-alpha.5
- Audit round 1 remediation (TP-5.5, ADR-0121): the first implementation audit of the 0.42 line (#539–#573) is closed — protocol hardening, a morph client rewrite, security hygiene and an evidence-honesty sweep.
- Headline root cause: the alpha.3 morph enhancement never fired — the
submitevent is not composed and page content lives inside page-element DSD shadow roots, so the document-level listener never saw enhanced forms. The client is rewritten around shadow-root submit interception and shadow-content morphing; the island-survival claims are now mechanically true (errata appended to the alpha.3/alpha.4 notes). - Protocol (ADR-0121): the prerender hard rule covers named
actions; named-action dispatch is own-key gated; onex-openelement-actionheader (true= ActionResult JSON,enhance= HTML morph) withVary; an action returning aResponseis a contract violation; the default PRG strips the?/namemarker; every 3xx coerces to 303 on POST andredirect()validates its status; fetch callers always receive ActionResult JSON (404/500 included, production-scrubbed); request-time responses carryCache-Control: no-store; POST takes the same error boundary as GET; action POSTs get a 10 MB body limit; non-GET/POST methods answer 405. - Morph continuity: form-scoped
data-open-regiontargeting with navigation fallback, id-keyed + lookahead identity matching, popstate reload,open:action-failurerestored (cancelable), submitter name/value preserved in the enhanced body, 500/cross-origin responses navigate instead of morphing, double-submit guard, fragment preservation,<details>/media state protection. The full survival matrix is documented indocs/current/MORPH_CONTRACT.md. - Evidence: the request-time fixture suite (42 tests) runs on Chromium,
Firefox and WebKit in the ci and release gate tiers; a static-output
determinism gate ships (
check:static-output-freeze); a dev(hono) vs build(Nitro) parity contract test boots both real servers; the perf baseline records its environment (docs/release/v0.42.0-alpha.5-performance.json). - Also fixed along the way: dev SSR crashed on every route (missing
customElementspolyfill — now shipped to the dev entry);[...path]request-time routes; zero-island apps with enhanced forms (the enhancement layer is emitted only when enhanced forms exist, so island-only sites keep their lean bundle); the starter's/contactroute (it was never shipped inTEMPLATE_FILES) now builds and is POST-smoked in consumer CI; SPA vs request-time loader/action types and docs are honest; a CSRF threat-model page ships in the guide.
0.42.0-alpha.4
- Hardening and recipes (TP-5, ADR-0120): the 0.42 line closes with integration proof instead of new semantics.
- Validation recipes verified in CI: zod (
/register) and valibot (/subscribe) run inside fixture actions with 422/303 asserted in three engines —docs/integrations/validation.md. better-auth and Drizzle recipes are published as doc-level (honestly marked unverified):docs/integrations/better-auth.md,docs/integrations/drizzle.md. - The
createstarter gains a request-time/contactroute exercising the full loop (rendering: 'dynamic'+ action +data-open-enhance), so starter consumers get the loop out of the box. PACKAGE_SURFACE.mdrecords the 0.42 line additions as unfrozen with their freeze target.- Performance baseline for 0.44: request-time render on the fixture is
cold 28.6ms, warm p50 1.58ms / p95 2.97ms
(
docs/release/v0.42.0-alpha.4-performance.json). - Fix (from alpha.3): the morph could replace an island whose light DOM carried whitespace-only text around the DSD template, resetting its state; the comparison now ignores whitespace-only text nodes, covered by the survival matrix in three engines (42/42).
0.42.0-alpha.3
- Revalidation continuity (ADR-0120): enhanced forms (
data-open-enhance) now morph the returned document into place instead of reloading — submission returns the same HTML the no-JS path renders (303/422), the client morphs it, andhistory.pushStatefollows the PRG target. - Island survival: a hydrated island whose light-DOM surface is unchanged
in the incoming document keeps its shadow state (the DSD template child
is excluded from the comparison). Islands whose surface changed are
replaced;
data-open-preserveexempts any subtree; the island client script is never re-executed by a morph. - Named regions: a
data-open-regioncontainer limits the morph to the matching region when present. - The ActionResult JSON path remains for custom clients; the built-in enhancement uses HTML morphing for continuity.
- Fixture proof: counter island at 3 survives a 422 morph and a PRG morph; static/request-time mixed navigation — Chromium, Firefox and WebKit, 36/36.
0.42.0-alpha.2
- The form/action loop (ADR-0120): plain HTML forms work without
JavaScript on
rendering: 'dynamic'routes. - Protocol: actions run before loaders (revalidation invariant);
fail(4xx, data)returns take the 422 re-render channel with the echo; successful mutations answer 303 (PRG) — never a 200 render; redirects thrown from actions coerce to 303; POST without an action is a defined - Named actions dispatch via
formaction='?/name'(export const actions = { name(ctx) {...} }); unknown names are a defined 404. - Fetch callers (
x-openelement-actionheader) receive theActionResultdiscriminated union (failure/redirect/error); the island client entry enhancesdata-open-enhanceforms with the same protocol and no DOM surgery — unhydrated islands are untouched, failure falls back to the native 422 render unless the page handlesopen:action-failure. - Contract: an action must be safe to re-run after a failed validation (validate first, mutate after).
- e2e: the full loop passes with
javaScriptEnabled: falseand on the JS enhancement path — Chromium, Firefox and WebKit, 33/33.
0.42.0-alpha.1
- First alpha of the 0.42 line (ADR-0120): request-time rendering gains
semantics —
renderIntent.modewas inert metadata before this release. rendering: 'dynamic'routes skip prerendering, dynamic expansion and i18n locale prerendering; they are served per request by the generateddist/server/index.js(nitro-mount over the same SSR bundle), withdist/server/server-manifest.jsonrecording the partition.- Hard rule (ADR-0120): pages with actions cannot be prerendered — a route
module exporting an action without
mode: 'dynamic'fails the build. - BuildPlan evidence records
requestTimeRoutes; pure-static projects emit no new artifacts (byte-identical public output proven against the 0.41.2 build: zero HTML/JS/CSS differences). - Request-time e2e fixture under
packages/adapter-vite/__fixtures__/request-time/proves loader data varies per request and islands hydrate identically to static pages (Chromium, Firefox and WebKit, 12/12). - Request-time HTML now receives the island client entry automatically —
the generated server entry injects the same script the static pipeline
injects post-build (found by the fixture; without it, islands on
request-time pages never hydrated). A latent
__headExtras is not definedcodegen bug for projects without head extras is fixed too. - Loader/action contract types (
Loader/LoaderContext/Action/ActionContext) are unchanged — they already shipped; this alpha wires the rendering-mode semantics around them.
0.41.2
- Patch release: release-tooling self-repair (TP-0 of the 0.42.0 plan) — no public API, topology or runtime-default changes.
- A resumed patch release no longer skips a version: the target is
re-derived from recorded evidence when a previous attempt already bumped
the package line (the 0.41.1 → 0.41.2 incident, reverted in
10038c4d). - New release line-prose gate: the version-anchor bump records the www
roadmap current-line entry's superseded theme in
tools/project-constants.ts, and the www truth gate fails a release until the new release theme is written (the 0.41.1 bump had shipped alpha.19's theme under thev0.41.1timeline entry).
0.41.1
- Patch release: tooling hardening and hygiene from the third-party audit's fixable set — no public API, topology or runtime-default changes.
- adapter-vite
dist/.openElementmagic strings converge on sharedinternal/paths.tsconstants;tools/lib/fs.tsgains sharedreadText/readJsonused across ten tooling files. - The repo-hygiene gate now scans credential files and credential-shaped content and rejects tracked binaries over 1 MiB outside intentional design/e2e/fixture locations.
- vite 8.0.10 → 8.0.16 across root, examples and adapter-vite (the latter's pin was the hidden cause of a tsc crash on dual-config typechecks).
- Version guards learn the stable line: www-truth retires the same-base alpha line instead of disabling itself on stable versions, publish dry-run skips already-published versions, and stale-claim fixtures no longer assume an alpha current line.
CONTRIBUTING.mdrecords theno-sloppy-importsrationale; stale merged branches were pruned.
0.41.0
- Stable five-package release (ADR-0119): the interface freeze covers
defineElement,definePage,buildApp, the package graph, the supported subpaths and the static/SPA semantics ofdefineApp; request-time data, forms, sessions and cache stay explicitly unfrozen until 0.42/0.44. - Adapter-vite internal subpaths pruned at the freeze (
app-vite,build-context,head-injection,i18n-plugin,plugin,generated-data-resolver,plugin-mdx,route-manifest,cli/build-client,cli/build-ssg) — use the root,nitro-mount,cli/buildandsitemapinstead (breaking; see the migration guide). - The #390 external adopter pilot is retired by maintainer decision after zero recruitment (recorded exception, not replaced with internal evidence); the seven-day P0 watch on the 0.41.x patch line starts at this release.
- Aggregate migration guide from 0.40.x and every alpha line release:
docs/release/v0.41.0-migration.mdand the site's/guide/migrationpage. - ui control geometry is squared (
--btn-radius,--badge-radius,--ui-control-radius:--radius-round→--radius-1, 6px) — visual breaking change; update screenshots and custom control CSS. - The release verifier now supports stable
x.y.zversions (prerelease-only before), and the version guards stay honest on a stable current line.
0.41.0-alpha.19
- Third audit round cleanup sweep (ADR-0118, issues #481-#506); no new product surface.
- Fixes the reflect removal suppression (Boolean
default: truedesync), the popstate redirect-then-block URL fork, and For drift-token separator collisions; the reflect browser spec joins the Firefox/WebKit smoke gates. - Closes the export-star seams: the element root switches to explicit type
export lists,
SafeHtml/UnsafeHtml/StyleSheetRuleleave the root for real, and the internalopen-element-render/open-element-hydrationsubpaths are pruned from element exports (breaking type-surface changes; see the GitHub prerelease notes for migration). - Single-sources
HYDRATION_STRATEGIESand the routeInfo contract, sinks the release executor intorelease.tswith orchestration tests, and preserves curated release-note sections so migration records stay in the durable record. - Mechanizes the audit's edge findings: www truth catches bare version
mentions, anchor gates catch body drift, the assertion-style gate covers
every package test, graph direction rules are explicit, and the deno-api
check catches
globalThis.Deno/destructuring/npm:patterns. - Deletes the third-round dead-code inventory (renderDsdStream, bindHydrateEvents, generateHonoEntryCode, tools/test-fixtures, orphan tasks, dead config entries) and rewrites the always-true test assertions.
0.41.0-alpha.18
- Fixes the
reflect: truestatic-prop write loop and SSR attribute overwrite; resolves the root-level<Show>/<For>CSR edge; unifies prop attribute casing; makesForbranch tokens content-sensitive; fixes client-runtime double hydration; runs router guards on history traversal; honorsprefers-color-schemein theme-init. - Shares one CEM admission plan across dev/SSR/SSG; dynamic-route render
failures now fail the build (opt-out
'warn'); failed pages never ship nor enter the ISR manifest; static non-200 outcomes are summarized. - Local releases land evidence and closure on main; anchor gates reject stale version claims; the bump maintains every currency line; the release executor resumes from failures.
- Adds WebKit smoke to CI, gates examples checks, single-sources the guide with real Chinese rendering, and covers the SPA action chain in a real browser.
- Removes dead exports, fields and scripts (breaking; see the GitHub
prerelease notes for migration), removes
renderIntent.streaming, converges fmt/lint exclusions, and retires stale files and config entries.
0.41.0-alpha.17
- Covers hydration and binding behavior in a real browser: signal text patching, event hydration, SSR/hydration mismatch fallback and form submission through shadow boundaries.
- Wires SSR error collection: a failing route render produces a defined 500
result with
RenderErrordiagnostics; the unreadhydrationHintscontract is removed. - Converges island declaration construction, single-instantiates the entry
descriptor, deduplicates the SPA/SSG phase-2 blocks and shares route
rendering helpers; deletes the unwired external-resolver, the
clientOnlyTagschain and dead build-context fields. - Counts every source file in the coverage denominator and re-baselines thresholds on measured values; the critical-path gate runs its e2e suites for real and can no longer skip them on failure output.
- Adds a Firefox smoke project to CI for the core DSD/hydration/theme specs.
- Adds a mechanical version-anchor gate across governance documents, and
the release bump now maintains
ACTIVE_EXECUTION_VERSION. - Fixes
publish-existingevidence: records the true previous package line, rewrites GitHub release notes from completed evidence, and generates the release closure record automatically. - Moves adapter build-time utilities from the
@openelement/elementroot to@openelement/element/build-utils, stops exporting internal router types from the@openelement/approot, and alignsPACKAGE_SURFACE.mdwith a machine-checked exports inventory. Breaking surface removals: element root build utilities (migrate to./build-utils), app rootRouteConfig/RouterInstance/RouterModetypes, adapter-viteExternalManifesttype andSsgPageOutput.hydrationHints. - Publishes the #390 external adopter pilot kit and launches recruitment.
0.41.0-alpha.16
- Fixes unknown dynamic-route params serving 200: a
notFound()thrown from a page element's render now propagates through the DSD render chain as protocol control flow (duck-typed alongside redirect) so the request-time server entry answers 404 (#922). The starter blog route now signals not-found this way instead of rendering a 200 "Post not found" page. - Aligns SSR and hydration event markers for custom-element hosts and
Show/Forbranches; hydration validates marker counts and branch tokens and falls back to client re-render on mismatch. - Merges static-props
observedAttributesat class-definition time so attribute-to-signal synchronization works in real browsers. - Matches island chunks via the client build manifest, fixes base64url hash
handling, names
.tsx/.jsxisland chunks, and normalizes Windows drive-letter island paths (#460). - Enforces the npm
latestdist-tag invariant for prereleases in the publish tooling and release verifier. - Clears current-truth drift across governance documents and removes dead gate triggers (ADR-0116 packages A and E).
0.41.0-alpha.15
- Modernizes the CI runtime (GitHub Actions Node 24 with reviewed immutable SHAs) and makes external review advisory.
- Enforces current-truth wording mechanically across governance documents and the website.
- Ships the #390 external-adopter pilot kit, cross-platform published-consumer runs and a five-package public-interface snapshot for the freeze rehearsal.
- Records the stable-readiness dossier; #390 and #37 remain open by design.
0.41.0-alpha.14
- Recovers the release line with an exact-version starter, verified published consumers and honest two-stage release evidence.
- Publishes all five packages under the
alphadist-tag with post-publish Deno, Node ESM, Nitro and third-party Web Component smoke evidence.
0.41.0-alpha.13 (publication failed; changes shipped in alpha.14)
- Removes the alpha-only
defineLayoutalias; usedefineElementwith the same arguments for layout elements. - Restores declared static-prop defaults when reflected attributes are removed.
- Hardens SSR prop injection, custom-element hydration, params parsing, nested SSR depth, and adopted stylesheet composition.
- Stabilizes SPA action errors, caches same-route GET requests, bounds render data contexts, and compiles client routes into a declaration-ordered trie.
- Removes Preact bridge top-level await and public data-context mutation hooks.
- Hardens Adapter Vite i18n, head sanitization, sitemap, island manifests, npm-specifier rewriting, asynchronous manifest reads, CORS defaults, and AST-based route metadata extraction.
- Moves UI tokens to a CSS source of truth with generated-output drift checks, and makes Create template generation asynchronous, deterministic, and bound to the five-package same-version release invariant.
0.41.0-alpha.12
Audit-remediation foundation release: closes the 13 high-severity findings
from the 0.41.0-alpha12 full code audit (issues #424–#428). No in-repo
release note was written at release time; the retrospective gap note is
docs/release/v0.41.0-alpha.12.md.
- Fixes core runtime issues, including the
signal-contextinfinite loop andErrorBoundaryretry. - Hardens SSG/build: command-injection closure, dynamic-route encoding, and
pure-Node
process.cwd()compatibility. - Repairs contract-checker correctness and backfills release-tooling tests.
0.41.0-alpha.11
- Restores frozen-install and changed-path/release workflow truth.
- Fixes query decoding, SPA page-host data, dialog inert restoration, and theme propagation.
- Consolidates the Element/Adapter protocol seam and removes verified dead DSD, CEM, route-scanner, and UI escape code.
- Repairs clean Nitro Workers builds, semantic visual smoke, and package artifact allowlists.
- Enforces publishable runtime coverage at 69% lines, 81% branches, and 72%
functions; published with tag, GitHub prerelease and post-publish consumer
evidence (see
docs/release/v0.41.0-alpha.11.md).