Skip to content

Feat/svelte extraction binding - #84

Merged
codecaaron merged 10 commits into
mainfrom
feat/svelte-extraction-binding
Aug 13, 2026
Merged

Feat/svelte extraction binding#84
codecaaron merged 10 commits into
mainfrom
feat/svelte-extraction-binding

Conversation

@codecaaron

Copy link
Copy Markdown
Owner

No description provided.

codecaaron and others added 10 commits August 10, 2026 17:42
…xtraction-only system binding

The Svelte arc, rebased clean onto current main (replaces the local
merge-based chain, preserved at backup/main-with-bench):

Usage-extraction poc — shared raw-source ingestion boundary
(source-ingestion.ts) with the native Svelte source adapter projecting
.svelte usage facts into the OXC pipeline; framework-neutral
class-resolver runtime entry (@animus-ui/system/class-resolver) with
runtimeImport plugin override; Svelte 5 e2e canary (client + SSR builds,
generated-CSS and runtime-HTML assertions); dual outside-repository
packed consumers (resolver-only production + full authoring).

React-absent authoring (svelte-extraction-only-system-binding, inc 01):
- D1: resolver definitions bind the configured system through a
  type-only import + declared chain root under required strict
  extraction; the application module graph never evaluates the
  React-reaching builder barrel.
- D2: the Vite geological reset snapshots replacement plans, diffs them
  after successful publication, and evicts changed source modules
  across every environment graph before the full reload; focused
  falsifier tests cover changed/equal/failed-reset arms with a
  demonstrated red.
- D3: React removed from the Svelte authoring manifests (exact
  @types/react retained per DEF-2); packed verification proves React
  undeclared/absent/unresolvable through strict TS, a specifier-
  rewrite-aware middleware-mode dev transform probe, client/SSR
  builds, and runtime assertions.

Also: parity corpus gains the two Svelte integration units (refreshed
under svelte-usage-extraction-poc-corpus-20260809 against the
transform-sources oracle); packages/_bench/ and .vite-hooks/ are now
gitignored local tooling.

Gates: verify:packed green end-to-end, G2 probe exact, G3 focused
16/16, compile / 1282 TS units / 165+1 integration / 16 dependent-owner
tasks green; subagent cold review findings dispositioned.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…gestion arc

Incremental quarantine parity (F4/F5/F6): withoutInvalidOriginals moves to
the shared pipeline and every incremental path — hmr edit, delete prune,
transform detection, rediscovery fold, vite geological reset, next
incremental batch — quarantines invalid originals per-file exactly like
buildStart instead of aborting the whole re-analysis on any corpus
diagnostic (which froze HMR on default config: .mdx in DEFAULT_EXTENSIONS
with the optional peer absent). Deletes never restore pruned entries (one
watcher event means a restored entry is a permanent ghost), the .mdx fold
guard is back, warns dedupe per (path, line) and clear on clean
republication, and next's misleading 'idle' status write on abort is gone.

Advisory parse diagnostics (F1): recovered OXC parse notes warn in every
mode, never strict-throw, never quarantine — extraction must not be
stricter than the host bundler (JSX in .js builds again; full JSX-in-.js
support via analysis-path rewrite deferred: it moves plan keys).

Resolver index (F2 rejected, F3 fixed): renamed re-exports KEEP failing
closed — live probes against the real engine show usage attribution
follows same-name barrel hops but not renames, so witnessing renames
would silently lose usage; the boundary now carries its engine-layer
proof test and true rationale. NodeNext relative specifiers with emitted
extensions (./definition.js) resolve to their source modules, proven
end-to-end through engine pruning.

Adapter fail-open shapes (F7/F9/F10): the callable string form witnesses
identically to .attrs() under the same argument/access rules; module-
script imports are in scope for instance-script calls with the import
copied into the projection; the template fragment is scanned (dedicated
walker — Fragment containers carry no spans) and resolver calls there
fail closed with SVELTE_ATTRS_TEMPLATE_UNSUPPORTED.

Host coherence (F11/F12/F13/F14): dev fileCache seeds from the accepted
corpus before the analysis gate (a failed non-strict buildStart no longer
strands HMR with a one-file universe); runExclusiveAnalysis serializes
transform detection, hot updates, and geological resets per context; the
external-token join runs in publishSourceIngestion after generated-child
owners land (next-plugin ordering parity); a runtimeImport override
throws in every mode when any replacement needs createComponent/
createComposedFamily, naming the offending components.

Parity honesty (F15): the integration corpus enumerates .ts and refuses
zero-file units — svelte-usage gains its real chain surfaces, the hollow
svelte-lifecycle unit leaves the corpus (65/65), refreshed under
svelte-parity-corpus-enumeration-20260810 with the register cycled back
to empty. F8 documented as the inline-literal pruning rule; dead
buildFileEntriesFromCache removed.

Gates: compile all packages, 1293 TS units, integration (incl. live
barrel-boundary and NodeNext probes), G3 focused 18/18, canary, parity
65/65 both modes, 16 dependent-owner tasks, packed end-to-end, lint/fmt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…es JSX-enabled

Renamed re-export attribution (lifts the svelte fail-closed boundary):
resolve_usage_identity walks renamed chains to the defining binding —
sourced re-export hops via follow_reexports, defining-module local
renames (export { badge as fancyBadge }), and import-then-local-export
barrels (import { badge } …; export { badge as pill }), cycle-guarded,
alternating until a chain id lands. A renamed consumer's usage now
reaches the chain, so another consumer's literal can no longer prune the
variant a renamed import renders. The integration falsifiers caught the
import-then-local-export shape missing from the first implementation
before it could ship as silent fail-open. TS-side, the resolver index's
name-equality gate is lifted (renames classify as resolvers), the
fail-closed tests flip to witnessing, the live boundary test proves
renamed pruning end-to-end through the real engine, and the guide's
boundary section moves renames into the supported set.

JSX in .js: source_type_for parses .js JSX-enabled — the Babel/SWC/
esbuild ecosystem norm (CRA / legacy-React / Next pages/*.js). This is
the deliberate alternative to the analysis-path rewrite, which would
have churned replacement-plan keys for every .js consumer; recorded as
an explicit deviation from the standing TS-side-rewrite preference,
whose premise (rewrite is the cheap path) inverts here. JSX grammar
activates only at expression start, so plain-JS comparison chains are
unaffected (covered). Recovered parse diagnostics remain advisory for
genuinely malformed sources.

Gates: extract-v2 553 units (renamed hops red-checked via removal),
clippy -D warnings, cargo-machete, canary, parity 65/65 both modes with
no baseline drift, integration 166+1 todo incl. flipped renamed-barrel
receipts, TS units 1293, compile, lint/fmt.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…d session spine

The CLI commit moved the session spine from next-plugin/src to
packages/extract/session and replaced per-test vi.mock singleton stubs
with the setEngineApiOverride seam; the gauntlet commit replaced raw
exclude patterns with ExcludeMatcher. This merge carries pr-84's source
ingestion (ingestRawSources / surfaceSourceDiagnostics / publish) onto
the moved spine, keeps the seam-based test injection with an added
extractFacts stub, and adopts ExcludeMatcher at both resolveScanConfig
call sites. shouldHandleMdx/missingDepFlag locals dropped: MDX
preprocessing now lives inside ingestSourceEntries. bun.lock
regenerated from the merged manifests.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…errides

The merged session requires extractFacts for source adaptation; these
three files' seam overrides predate pr-84 and auto-merged without it.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The vi.mock targeted the pre-hoist '../src/singleton' path deleted by
the session move; the seam override preserves the test's conditional
extractFacts-absent arm, and engineApi now resolves through the moved
singleton (the seam key survives resetAnimusGlobals by design).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…on per host

Hoists the forked surfaceSourceDiagnostics / ingestRawSources policy
into createSourceIngestor (pipeline-owned: capability guard, warn-dedupe
lifecycle, per-host prefix; restores the prefixed-warn parity next-plugin
had drifted from) and adds a host-owned facts memo so incremental corpus
passes re-extract only changed entries instead of re-parsing the whole
project through the native boundary on every HMR/watch event.

Collapses the ingest -> quarantine -> analyze -> publish transaction,
previously open-coded at 8 call sites with five publish-guard spellings,
into PluginContext.analyzeIngested (beforeAnalysis hook carries the two
documented ordering constraints) and the session's ingestAccepted core.
The context probe mirrors the real transaction over its overridable
parts. hmr's per-event O(corpus) entry scan is now an O(1)
analysisEntryCache read. addAnalysisEntry/addAdaptedEntries became
closures; identity entries reuse the original's hash instead of
re-hashing the corpus every pass; ResolverExportIndex memoizes
attribution and relative resolution.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
svelte-source-adapter: byte offsets take an ASCII fast path (was a
prefix copy per span endpoint — quadratic per adaptation); import
bindings compute once per program instead of twice each for module and
instance; script/fragment AST walks skip entirely when no candidate
import binding exists; svelte/compiler loads through a success-memoized
dynamic import (missing-peer still retries, so mid-session installs
recover).

createClassResolver: the callable string form resolves classes directly
instead of building and discarding the attributes object and its
serialized style string on every render.

discover-packages: preprocessFile survived the move of MDX adaptation
into ingestSourceEntries with both callers passing identity — replaced
by the optional onSourceRead observer, which names what the session
actually does (record raw-file identity); the null-skip and path re-key
branches retire with it.

extraction-session: the 11-field snapshot/restore parallel lists become
snapshotSourceState/restoreSourceState — one field list, Object.assign
restore that cannot omit a member.

Removed: PluginContext.analysisEntries() (zero callers),
SVELTE_RUNTIME_SPIKE.md (superseded tombstone pointing at a gitignored
path; README now points at the committed e2e fixture).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
The guide previously lived only at docs/svelte.md, which the bare
'docs' gitignore entry swallows — unreachable in-tree and linked from
README as a dead path. It now ships at /docs/advanced/svelte in the
showcase (nav entry + MDX page; the content glob picks it up), and the
README points at the guide plus the e2e/svelte-app working consumer.

Verified: page renders at /docs/advanced/svelte with zero console
errors (all four sections, six highlighted fences, strict-mode callout,
sidebar entry) and the showcase owner claim (build + assert + Wrangler
dry-run) passes.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
@codecaaron
codecaaron merged commit 9295baf into main Aug 13, 2026
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant