feat: implement Beta.2.1 unified Router and standalone Element tooling - #1343
Conversation
|
APIError: Insufficient Balance |
|
Maintainer-approved Beta.2.x plan updated on 2026-09-08 in planning PR #1342, ADR-0152, VERSION_PLAN, 15 existing issues and Project 3.
The review comment #1343 (comment) says APIError: Insufficient Balance. The review workflow's SUCCESS is not a completed review. #1332 explicitly owns service recovery and failure propagation as an immediate merge prerequisite, not deferred cleanup. No provider/model or billing changes have been made. #1343 remains incomplete: SSG output/navigation findings, fork migration/memory baselines, actual review, final-SHA CI and fresh verifier evidence are outstanding. Confirming #1342 ancestry is not a claim of baseline CI success. These planning updates do not repair product code or authorize release. Consume the updated #1342 planning contract before continuing implementation. |
…roved contracts)
Consumes planning HEAD dcfa2ee. toSSG discovery via app.routes yields nothing behind app.all('*', dispatcher) (middleware arity filtered); project eligible static pages (rendering!=dynamic, non-dynamic) for discovery only, render through real app.fetch/request. Preserve host routes, exclude wildcard. Align default mock dispatcher with routeInfo. Fixes RED ssg-render record test; www build 150 pages, /,/docs,sitemap present.
…oller POST with formData leaves to browser/server before pending/intercept; fragment-only and reload default browser-owned in history mode, hash semantics separate. Each spa mount gets a fresh AbortController; stale loader/action results never commit. Tests: native ownership unit (POST/fragment/reload/GET), mount fresh signal (mount/dispose/remount, direct remount stale, action signal), 3-browser POST/fragment/reload proof + existing nav regression.
The ADR-0152 chain (beta.2.1-beta.2.3, then 1.0.0-alpha.1) is planned, not retired: derive exemptions from lib/version.ts checkpoint/stage successors instead of banning every non-current prerelease. Unapproved prereleases (beta.3, historical 0.44.0-alpha.N) stay forbidden; the alpha.N shorthand no longer matches inside an exempted full version. Fixes the www build artifact-truth failure introduced by consuming planning HEAD dcfa2ee.
The review action posts provider errors as PR comments while exiting 0, so the green wrapper was not review evidence (observed on #1343: APIError Insufficient Balance). A Deno gate now verifies the step outcome and the run-attributed review comment, matching structural provider/API error signatures across billing, rate-limit, auth, availability, timeout and model categories; absence of evidence fails closed. Provider restoration itself needs external billing action and stays a merge prerequisite.
…patch fullstack:boundary-check sliced per-route app.get/app.post registrations; the unified dispatcher keeps per-record handlers in the generated __pageHandlers method table. Slice that table instead, preserving the ADR-0121 no-store assertions (non-vacuous GET presence, baseline emission, public-cache rejection). Drop the duplicate route.path from the file-routed configuration examples: file paths own generated route paths (ADR-0152). Wire the standalone Element packed-consumer proof as a deno task.
Deploying openelement with
|
| Latest commit: |
5a6c925
|
| Status: | ✅ Deploy successful! |
| Preview URL: | https://44390ee9.lessjs.pages.dev |
| Branch Preview URL: | https://codex-beta2-1-router-core.lessjs.pages.dev |
|
APIError: Insufficient Balance |
The planning rewrite of roadmap.tsx quotes object keys ('stamp': …); the
AST extractor only accepted identifiers, so no CURRENT entry was found.
Accept string-literal keys as well.
|
APIError: Insufficient Balance |
open-element/url-pattern-list @00bface carries the qualified implementation, Node-native differential tests and the four construction/hit/miss/memory benchmarks. The embedded copy remains the production matcher until the separately authorized npm publish unblocks consumption (#1324).
|
APIError: Insufficient Balance |
|
APIError: Insufficient Balance |
…tePatternComponents The RouteRecord.pattern type narrowing drifts the public shape hash and generated API reference; both artifacts are regenerated, not hand-edited. Also drop the provider name from VERSION_PLAN (role-neutral docs gate).
|
APIError: Insufficient Balance |
…olicy The module header still described the gate as a merge prerequisite; the authoritative policy is supplemental + non-blocking with mandatory detection/reporting. Behavior unchanged.
|
APIError: Insufficient Balance |
The ADR-0152 chain (beta.2.1-beta.2.3, then 1.0.0-alpha.1) is planned, not retired: derive exemptions from lib/version.ts checkpoint/stage successors instead of banning every non-current prerelease. Unapproved prereleases (beta.3, historical 0.44.0-alpha.N) stay forbidden; the alpha.N shorthand no longer matches inside an exempted full version. Fixes the www build artifact-truth failure introduced by consuming planning HEAD dcfa2ee.
The planning rewrite of roadmap.tsx quotes object keys ('stamp': …); the
AST extractor only accepted identifiers, so no CURRENT entry was found.
Accept string-literal keys as well.
Additive tooling for the docs gates: the approved chain (beta.2 -> beta.2.1 -> beta.2.2 -> beta.2.3) plus the admitted product-stage transition to 1.0.0-alpha.1, matching the implementation branch's lib/version.ts so both branches evaluate the same planned chain. No existing consumer behavior changes.
#1342's 2026-09-09 planning update (ac0f9b5) plus its CI repairs (docs-gate planned-chain exemption, quoted-key roadmap parsing, version successor exports, content graph). Conflicts resolved by ownership: planning docs take the planning branch's authoritative wording; tools/lib/version.ts keeps the implementation branch's superset; the content graph is regenerated, never hand-merged.
|
APIError: Insufficient Balance |
…ad55e8) Planning truth now flows from dev ancestry. Conflicts resolved by responsibility: RELEASE_POLICY takes the landed planning text plus the version.ts ownership paragraph; version tooling keeps the implementation superset; no product semantics changed.
|
APIError: Insufficient Balance |
…xactly (#1324) RouteTable now consumes the OE-maintained fork from npm (exact pin, lockfile integrity matches the published artifact) instead of the embedded production copy, which is deleted. Package-graph rules encode the new edge (app -> url-pattern-list, external release line); publish tooling keeps the fork dependency exact in packed metadata while other externals keep caret ranges. The differential oracle corpus stays as integration tests against the real package (addPattern registration); its baseURL/exec pass-through oracle now mirrors the upstream-aligned inputs contract. SEMANTIC_OWNERSHIP names the published package as the matching authority.
|
APIError: Insufficient Balance |
…lockfile Required propagation, not drift: the starter consumes workspace app/adapter source directly, so its lockfile must carry the newly consumed @openelement/url-pattern-list@0.6.0 (exact, registry-matching integrity) and the typescript entry the workspace build path resolves. No example content, routes or semantics change; the freeze on examples/** otherwise stands (#1311).
|
APIError: Insufficient Balance |
- tools/check-url-pattern-list-release.ts: fail-closed live npm provenance gate for the exactly pinned @openelement/url-pattern-list fork — exact-pin declaration in both import maps, lockfile resolution + integrity, registry name/version/license/repository metadata, dist.integrity/shasum, tarball byte verification and content inspection (identity, entry points, LICENSE/README, file count, fork genericity). Wired as an AutoFlow ci/release tier gate and as a qualification leg; offline dev loops stay offline. - tools/qualify-v044-beta21.ts: the dedicated Beta.2.1 qualification lane. Executes router semantics, checkpoint version semantics, SSG authority, navigation on Chromium/Firefox/WebKit, packed starter/UI/standalone-Element consumers and (in CI, from trusted needs) the Node/Bun/workerd runtime floors, then writes v044-beta21-qualification.json only when every leg passed. Test-count floors, per-engine Playwright JSON accounting and packed-tarball existence keep every leg non-vacuous. - Table-driven v0.44 checkpoint acceptance: beta.2 -> beta.2.1 -> beta.2.2 -> beta.2.3 chain, beta.3-vs-checkpoint separation, stage transitions and historical alpha protection in tools/lib/version.test.ts and tools/bump-version.test.ts. - autoflow-ci.yml: beta21-qualification job on the exact PR head SHA uploads the SHA-named qualification artifact and joins the pr-full-ci-evidence required set (loop-evidence.ts + lockstep tests updated). - docs/runbooks/beta21-qualification.md documents what the mechanisms prove, when they run, the artifact they generate and how release verification consumes it.
|
APIError: Insufficient Balance |
#1343) Maintainer review: the dedicated beta21-qualification CI job, the tools/qualify-v044-beta21.ts orchestrator, the added version-semantics table tests and the runbook were version-specific permanent architecture and are removed. The checkpoint chain stays pinned by the pre-existing tools/lib/version.test.ts coverage. Kept: the generic, reusable url-pattern-list registry provenance gate (tools/check-url-pattern-list-release.ts, url-pattern-list:provenance task, AutoFlow ci/release tier gate) — it closes the live-registry/lockfile/tarball integrity gap flagged by the previous audit and derives the expected version from the workspace declaration, so it is not tied to Beta.2.1.
|
APIError: Insufficient Balance |
SSG discovery (ssg-render.ts): dedupe host entries only when hono/ssg would itself discover them (method GET/ALL with a non-middleware handler). An exact-path middleware (ALL, arity 2) or a method-only host route (POST/…) is filtered out of discovery by hono, so letting it suppress the canonical GET entry silently dropped the page from a successful build. Regressions: exact-path middleware and POST-only host route keep canonical pages discoverable while host behavior is preserved. Client router (client-router.ts): pending execution is now invalidated at the ownership point — guard passed, latest ticket held — instead of at navigation-attempt time. A guard-vetoed programmatic navigation, popstate or native traverse therefore no longer aborts and discards the current route's pending render (the initial loader could leave the root empty forever). Latest-wins guard sequencing (#1023) and disposal invalidation are unchanged. Regressions cover vetoed programmatic navigation, popstate and native traverse at router level, plus pending-initial-loader and pending-subsequent-render survival at SPA level. The same-origin-intercept test is re-pinned to the ownership-point timing and the fake navigate event now captures and drives the intercept handler.
|
APIError: Insufficient Balance |
|
APIError: Insufficient Balance |
Beta.2.1: Router/core convergence, standalone Element, prerelease semantics
Target
Beta.2.1 implementation for #1320, #1323, #1324, #1325 and #1338, under ADR-0152 and
docs/current/VERSION_PLAN.md. #1342 has landed (squash merge3ad55e84intodev;its qualified head
bc73198cwas green at merge time, merged with expected-head-SHAprotection). This branch is refreshed onto the landed
dev(mergecdf7540c), so theplanning content now arrives through real base ancestry.
Architecture
pathis the only pathname truth;pattern(RoutePatternComponents) carries onlynon-pathname URL components and a runtime
pathnameis rejected, not silently honored.URLSearchParamsstay separate;router.searchParamshands outper-reader snapshots so loaders/actions cannot mutate router state.
the real dispatcher. Browser navigation keeps POST/reload/fragment/download/cross-origin
browser-owned; every mount gets a fresh AbortController; guard vetoes restore via a
marked replace navigation that the router never re-intercepts.
What Changed
to the URL winner; explicit HEAD wins, otherwise HEAD falls back to GET inside the
winner with an empty body.
(host routes preserved, wildcard excluded); the www build emits 150 static pages again.
signal per mount; stale loader/action/guard results never commit.
@openelement/adapter-vite/elementexposes the existing private compiler plugin forstandalone Element tooling; packed App/UI edges are optional peers.
(
beta.2 → beta.2.1 → beta.2.2 → beta.2.3 → 1.0.0-alpha.1by explicit product-stagetransition);
prereleaseNumberis documented as a legacy channel-level field.__pageHandlersmethod table (no-store assertions preserved, non-vacuous); www truthgates admit the approved planned version chain and quoted roadmap keys; the critical-path
gate tracks the renamed path-param evidence; the supplemental AI-review job reports a
missing/errored review as a warning instead of masquerading as green evidence
(non-blocking per the 2026-09-09 maintainer decision).
What Was Removed
method-dependent winner fallback; the duplicate
route.pathdeclaration in generatedrecords; the per-page Hono winner/405 paths;
pattern.pathnameas an override channel.Fork / Dependency Boundary
open-element/url-pattern-list@00bface02e3117222dea9c620a63792545f04c13(on top ofupstream v0.5.0
4911e649, history and MIT attribution preserved) carries the qualifiedimplementation: 109/109 Node-native tests after a clean
npm ci, ordered-linear-oracledifferential coverage on native and polyfill constructors with seeded/reduced failures,
and construction/hit/miss/memory benchmarks in its
BENCHMARKS.md(GC-controlled,retained vs transient; static-only 5000-pattern hit 0.0057ms vs linear 2.82ms; the
all-conservative scenario honestly degrades to linear). Two genuine upstream bugs have
recipient-native reproductions drafted in the fork's
docs/upstream-issues.md(unreported; upstream responsiveness is not an OE gate).
@openelement/url-pattern-list@0.6.0is on npm (maintainerapproved the scope correction to OE's own
@openelementorg; the GitHub repo name isunchanged). Registry-verified: version 0.6.0, MIT, repository → open-element/url-pattern-list,
upstream author attribution retained, integrity
sha512-djz6c4tih8BL1lonjr41iuoWGGF5pOgldEE0wOB/hzLLB4rS1MQHRQ2X3zM2XxnB6SX5Fphxx7uwTN/+ZDH//g==;clean-consumer install + runtime smoke pass. OE consumes it exactly: workspace import map and
packages/app/deno.jsonpinnpm:@openelement/url-pattern-list@0.6.0,deno.lockrecords theexact version with registry-matching integrity, and packed
@openelement/appmetadata keeps thedependency exact (no caret float). The embedded production copy
packages/app/src/internal/router/url-pattern-list/is deleted; provenance/divergence live inthe fork (PROVENANCE.md / DIVERGENCE.md / BENCHMARKS.md). The switch was the rehearsed small
diff (constructor entries →
addPattern); the differential oracle corpus remains asintegration tests against the real package.
Standalone Element
deno task consumer:packaged-elementproves author → compile → pack → install outside theworkspace → plain HTML → real registration/attribute/event updates in Chromium 147,
Firefox 148 and WebKit 26.4, with no Router/App/UI installed, no workspace aliases, a clean
browser module graph, 32 reachable declaration modules checked, and authored source maps
retained. The compiler stays private; this is a tooling subpath, not a public compiler API.
Version Semantics
Lossless multi-identifier parsing/comparison; checkpoint succession is explicit
(
nextCheckpointVersion), product-stage transition is explicit (1.0.0-alpha.1);historical internal
0.44.0-alpha.0–10stay unpublishable; channels map to dist-tags.beta.3ordering is legal SemVer but not an approved checkpoint (www truth gate rejects it).No package version was bumped.
Validation — exact final SHA
3302dd01Local (macOS arm64, Deno 2.9.0 / Node 24.18.0; Chromium 147 / Firefox 148 / WebKit 26.4):
deno task test: 1920 passed (105 steps) + supabase starter 150 passed, 0 failed.deno task build: full chain green; 150 static pages incl./,/docs,sitemap.xml(146 URLs); artifact-truth and link checks pass.
deno fmt --check,deno lint,deno task typecheck,arch:check,graph:check,workflow:check,docs:truth,actions:check-pins: all pass.171 + 171 passed; Deno-driven three-browser POST/fragment/reload and packed-Element
proofs pass.
consumer:packaged,consumer:packaged-ui,consumer:packaged-elementpassagainst freshly packed tarballs.
deno task test1922 passed(105 steps) + starter 150 passed, 0 failed; packages/app and adapter-vite suites pass
against the published package; the URLPatternList differential corpus runs against
@openelement/url-pattern-list@0.6.0itself. Browser navigation coverage runs in thisSHA's CI (chromium/firefox/webkit e2e inside autoflow-ci). Packed consumers
(
consumer:packaged,consumer:packaged-element— three browsers, andconsumer:packaged-uiin CI) were re-run against tarballs packed from this SHA.CI on this exact SHA: autoflow-ci PASS (21m17s full matrix: build, coverage,
critical-paths, chromium/firefox/webkit e2e, request-time/ui-dogfood fixture gates,
starter smoke, static-output freeze, packed consumers), pr-full-ci-evidence PASS,
Cloudflare Pages PASS, dist/server Node 20 + Node 24 + Bun smoke PASS, CodeQL /
dependency-review / workspace-qualification / Analyze PASS. The supplemental
reviewjob is green with a warning annotation (no review executed — see below).
Known Non-blocking External Conditions
APIError: Insufficient Balance(external billing action, [beta.2.3] Simplify CI and AutoFlow around final semantic responsibilities #1332). The review job reportsthis as a warning and stays green by maintainer decision; this run contributes zero
independent review evidence. Required CI gates, human review and the fresh verifier
remain the real gates.
dev(3ad55e84) and this branch is refreshed onto it;@openelement/url-pattern-list@0.6.0is published and consumed. No external deliveryinput remains for [beta.2.1] Maintain public URLPatternList fork and consume qualified releases #1324. Remaining gates: fresh verifier session and human review.
Release Impact
None: no version bump, tag, npm publish, deployment, merge or issue closure. Examples stay
frozen. Release state and evidence files are unchanged; Beta.2.1 publication remains a
separately gated decision.