Claude Cursor GitHub Copilot Skill

sveltekit-progressive-enhancement-review

Statically review SvelteKit forms and form actions for functional resilience without JavaScript (native method="POST" fallback) and for use:enhance customization correctness (ActionResult branch handling, cancel() feedback, redirect/invalidation behavior), flagging silent-failure

LLM Mart · 0 points · 0 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download vincentchuwaichow-vanguard-frontier-agentic-skills_frontend_sveltekit-progressive-enhancement-review-febe32a.zip · 10 KB
Part of vincentchuwaichow/vanguard-frontier-agentic — 293 skills

Install

skills CLI npx skills add https://github.com/VincentChuWaiChow/vanguard-frontier-agentic/tree/master/skills/frontend/sveltekit-progressive-enhancement-review
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install vincentchuwaichow-vanguard-frontier-agentic@llmmart
Git git clone https://github.com/VincentChuWaiChow/vanguard-frontier-agentic.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole vincentchuwaichow/vanguard-frontier-agentic collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

SvelteKit Progressive Enhancement Review

Purpose

Review SvelteKit forms and form actions for progressive-enhancement resilience — whether the form still functions via a native browser POST when JavaScript fails, is blocked, or hasn't finished loading — and for use:enhance customization correctness, without re-litigating server/client load-function placement, component styling, or routing precedence in every response. This skill exists because a form that "works fine" during manual testing with JavaScript enabled can still be a dead end for the measurable share of real users who hit slow/blocked/failed JS on real-world connections, and because a custom use:enhance SubmitFunction that only handles the happy path silently swallows every failure/error/redirect ActionResult, turning a broken submission into a UI that does nothing and tells the user nothing.

When to use

Use this skill when the user asks to:

  • review a new or changed <form> / form-action implementation before merge,
  • confirm whether a form "works without JavaScript",
  • investigate a report that a form submission silently does nothing (no error, no navigation, no feedback) when it fails,
  • audit a custom use:enhance SubmitFunction for missing ActionResult branches or unexplained cancel() calls.

Do not use this skill for:

  • internal admin tools explicitly scoped as JS-required — progressive enhancement may be intentionally out of scope there; confirm that scoping with the user before flagging anything,
  • +page.js / +page.server.js / +layout.js universal-vs-server load placement review — use sveltekit-routing-load-review instead,
  • pure visual/styling review of form markup with no functional or error-handling question in scope.

Context7 Documentation Protocol

  • Resolve the library ID with resolve-library-id (matched result: /sveltejs/kit) before citing any SvelteKit-specific claim about form actions or use:enhance.
  • Before asserting what the default, no-argument use:enhance provides, call query-docs against /sveltejs/kit for "progressive enhancement use:enhance" and quote the precise rule: use:enhance only applies to a <form method="POST"> that posts to an action defined in +page.server.js; used without arguments it emulates native browser behavior — it updates the form prop and page status on success, resets the form element, calls invalidateAll(), and handles redirects, error boundaries, and focus management automatically, all without a full-page reload. Do not assume feature parity with a generic SPA form-handling library; this behavior is SvelteKit-specific and documented, not inferred.
  • Before asserting what a custom SubmitFunction must reimplement, call query-docs against /sveltejs/kit for "customising use:enhance SubmitFunction ActionResult" and confirm: the SubmitFunction receives { formElement, formData, action, cancel, submitter } before submission, and may return an async callback receiving { result, update } — where result is the ActionResult (success | failure | redirect | error) and update triggers the default post-submission logic that would otherwise run. If the callback is supplied at all, none of that default logic runs unless the callback calls update() or manually replicates it (e.g. via applyAction(result)).
  • Verify the SvelteKit version installed in the repo (package.json) before asserting use:enhance or ActionResult shape details are unchanged from the queried docs — form-action APIs have evolved across SvelteKit majors.
  • If Context7 is unavailable, fall back to the official_docs URLs in this skill's metadata.json and label the claim documentation-based, unverified against current release.
  • Never assume applyAction or invalidateAll is called inside a custom callback without reading the callback body — their absence is exactly the defect this skill exists to catch.

Lean operating rules

  • First classify every <form> in scope as native-POST-capable (has method="POST" and a real action target resolving to a +page.server.js export) or JS-only (driven solely by a click/onclick handler with no native fallback) — do this by reading the markup, never by assuming.
  • A native <form method="POST"> with no use:enhance at all already works without JavaScript by default; that is the baseline SvelteKit contract, not a defect. Do not flag its absence as a finding on its own.
  • Bare (no-argument) use:enhance gets the full documented default behavior (form reset, invalidateAll, redirect/error/focus handling) for free — do not demand the caller reimplement anything for a bare use:enhance usage.
  • Every custom SubmitFunction callback must branch on result.type. A callback that assumes result is always a success (e.g., only reads result.data with no type check) is a silent-failure defect: failure/error/redirect results are dropped on the floor and the user sees nothing.
  • A cancel() call inside the pre-submission SubmitFunction body must be paired with a clear, user-facing reason (e.g., inline client-side validation message shown to the user) — a silent cancel() with no visible feedback is equivalent to a silent failure.
  • Do not accept "an error variable exists in component state" as proof that failures are surfaced to the user. Trace whether that variable is actually rendered in the markup and, for accessibility, associated with the form via a status-message pattern (e.g., aria-live region or equivalent) — an unrendered or unannounced error state is still a silent failure for sighted users tracking visually and a silent failure for screen-reader users regardless.
  • Treat any custom SubmitFunction that bypasses the form's native action/method to call a hand-rolled fetch() directly (rather than letting use:enhance submit natively or using SvelteKit's own deserialize()/applyAction() pattern) as a security-review flag, not a pure UX nit — it can skip origin-check behavior SvelteKit applies to form-action submissions; do not wave it through as a stylistic preference.
  • Never execute, build, or run application code as part of this review; this is a static-review skill (Read/Grep/Glob only). "Works without JS" claims must be verified by reading markup for method="POST" and a resolvable action, never assumed from a component name or comment.

References

Load these only when needed:

  • Review workflow and findings contract — use for the step-by-step review procedure, the decision tree for classifying findings, and the required output shape.
  • Failure-state and accessibility UX — load only when reviewing how a failed/error/cancelled submission is surfaced to sighted and screen-reader users, not for pure native-fallback presence checks.

Response minimum

Return, at minimum:

  • the form(s) and form action(s) in scope,
  • evidence level (repo evidence from markup/action code vs inference) and Context7/docs grounding used,
  • ranked findings (file:line, missing-fallback or unhandled-ActionResult-branch gap, fix sketch matching documented use:enhance/applyAction patterns),
  • verdict on whether any public-facing, unauthenticated-reachable form (signup, contact, checkout) lacks a native fallback — this is a hard stop, not advisory,
  • open questions (e.g., whether an internal tool is confirmed JS-required by design before exempting it).
Files (vanguard-frontier-agentic)
  • references
    • failure-state-and-accessibility.md 5 KB
      # Failure-State and Accessibility UX
      
      Use this reference only when reviewing how a failed, errored, or cancelled form submission is surfaced to sighted and screen-reader users — not for pure native-fallback presence checks (see `references/workflow-and-output.md` for that).
      
      ## What people get wrong
      
      The naive assumption is:
      
      > "There's an `if (form?.error)` block in the template, so failures are surfaced to the user."
      
      That is incomplete in two ways:
      
      1. **Rendered is not the same as announced.** A conditionally-rendered error `<p>` inserted into the DOM after a client-side (`use:enhance`) form update does not automatically get read by a screen reader unless it is associated with a live region (`aria-live`, `role="alert"`/`role="status"`, or equivalent) or receives programmatic focus. WCAG 2.2's status-messages guidance exists precisely because DOM insertion alone does not guarantee an assistive-technology announcement.
      2. **A variable existing in state is not proof it renders at all.** Component state (`form?.error`, a local `let errorMessage`) can be set by a callback and never referenced anywhere in the template — verify by reading the markup, not by trusting that a well-named variable implies it's displayed.
      
      ## Non-negotiables for this sub-review
      
      - Do not accept "the error is in the `form` prop" as sufficient. Trace whether the template actually reads that prop into visible markup.
      - Do not accept "there's a red error box in the design" as sufficient for accessibility. Confirm the error container has an appropriate live-region role/attribute (`aria-live="polite"` or `"assertive"`, `role="alert"`, or `role="status"`) or that focus is programmatically moved to it on failure — one of those two mechanisms is required for screen-reader users to reliably learn about an async/no-reload failure.
      - For forms that fall back to a full-page reload (no `use:enhance`, or `use:enhance` with `update()`/`applyAction()` invoked), server-re-rendered failure content read on page load is generally sufficient without a live region, because the new page load itself resets assistive-technology reading context — do not demand `aria-live` on a full-reload failure path; that is a false-positive pattern specific to no-reload (client-side-updated) failure states.
      - A `cancel()`-triggered client-validation message must follow the same rendering + announcement bar as a server-originated failure — a locally-cancelled submission is still a failed submission from the user's point of view.
      - Do not conflate "the form has a `required` attribute" with adequate failure messaging for server-side validation failures. Native HTML validation and server-side `ActionResult` `failure` responses are different failure paths; both need coverage, and a HIGH/MEDIUM finding about one does not resolve a gap in the other.
      
      ## Minimal safe pattern to expect
      
      1. Server action returns `fail(422, { error: '...', ...values })` (or similar) on validation/processing failure.
      2. Template renders `{#if form?.error}` (or equivalent) into a container that either:
         - has `aria-live="polite"` (or `role="alert"`/`role="status"` as appropriate to urgency), or
         - receives programmatic focus (`element.focus()`) when the failure state first appears.
      3. If a custom `use:enhance` callback is present, it either calls `update()` so the default `form`-prop-driven rendering above still fires, or manually replicates equivalent state-setting and rendering for every `ActionResult` branch it intercepts.
      4. Client-side `cancel()` paths render into the same or an equivalently accessible container, not a separate, unannounced one.
      
      ## Adversarial checklist
      
      - If you disabled CSS and squinted only at DOM order, would a screen reader announce this failure, or would it silently sit in the DOM until the next unrelated navigation?
      - Does the live-region/focus mechanism differ between the server-originated failure path and the client-`cancel()` path? If so, is that difference justified or is it an accidental gap?
      - Is the failure container conditionally *removed from the DOM* between attempts (which can suppress re-announcement of the same message on a second identical failure) rather than updated in place?
      - For a full-page-reload fallback path, did you correctly treat the absence of `aria-live` as expected rather than flagging it as a gap?
      
      ## When to push back
      
      Push back if the user asks to:
      
      - close a review of a public-facing form's failure UX solely because "there's an error variable" without confirming it renders,
      - skip the accessible-announcement check because "the design has a red box" — visual-only signaling is not sufficient for screen-reader users,
      - treat a full-page-reload failure path and a no-reload (`use:enhance`-intercepted) failure path as needing identical `aria-live` treatment — they don't; judge each by its actual reload behavior.
      
      Those are not shortcuts. They leave a portion of real users — those on assistive technology, and separately those with degraded/blocked JavaScript — with no way to know their submission failed.
      
    • workflow-and-output.md 8.2 KB
      # Review Workflow and Findings Contract
      
      Use this reference for the step-by-step review procedure, the decision tree for classifying progressive-enhancement and `use:enhance` findings, and the required output shape.
      
      > Version note: `use:enhance`, `ActionResult`, and `applyAction`/`deserialize` behavior are documented for current SvelteKit releases. Verify the installed `@sveltejs/kit` version in `package.json` before asserting exact default behavior applies unchanged; form-action APIs have shifted across majors.
      
      ## What people get wrong
      
      The naive assumption is:
      
      > "The form has `use:enhance`, so it's progressively enhanced and handles errors."
      
      That is wrong in two independent ways:
      
      1. `use:enhance` is not what makes a form work without JavaScript — the native `method="POST"` + resolvable action target does that, and it works with **zero** `use:enhance` at all. `use:enhance` only improves the *with-JS* experience (no full reload, focus management, etc.) on top of a fallback that must already exist.
      2. Adding `use:enhance` with a **custom** `SubmitFunction` callback does not inherit any of the documented default behavior (form reset, `invalidateAll`, redirect/error/focus handling) — supplying a callback opts out of all of it unless the callback explicitly calls `update()` or reimplements the equivalent via `applyAction(result)`. A callback that only handles the success path silently drops `failure`, `error`, and `redirect` results.
      
      ## Step-by-step workflow
      
      1. **Inventory forms in scope.** For every `<form>` in the reviewed files, record its `method`, `action` (or lack thereof), and whether it resolves to a real form action exported from a `+page.server.js`.
      2. **Classify native-fallback status.** A form is native-POST-capable only if it has `method="POST"` and a resolvable action. A form driven solely by a client `onclick`/`onsubmit` JS handler with no native `method`/`action` pair has **no** fallback — note this explicitly, it is the highest-severity category below.
      3. **Classify `use:enhance` usage per form**, one of:
         - absent (native-only; correct baseline if that's the intended UX, not a defect by itself),
         - bare/no-argument (gets full documented default behavior for free),
         - custom `SubmitFunction` with no returned callback (pre-submission-only customization, e.g. loading state; post-submission handling still defaults),
         - custom `SubmitFunction` with a returned callback (post-submission handling is now entirely the callback's responsibility).
      4. **For every returned callback, check `result.type` branching.** Read the callback body. Confirm it inspects `result.type` and handles (directly or via `applyAction(result)`/`update()`) each of `success`, `failure`, `error`, and `redirect` that the corresponding form action can actually produce. A callback that reads `result.data` unconditionally, with no `result.type` check, is a silent-failure defect.
      5. **Check every `cancel()` call site.** For each `cancel()` invoked in the pre-submission `SubmitFunction` body, confirm the surrounding code also produces a user-visible signal (e.g., sets a validation-message variable that is rendered) before or at the point of cancellation. A `cancel()` with no paired visible feedback is a silent failure from the user's perspective, identical in effect to a swallowed `ActionResult`.
      6. **Trace failure-state rendering**, not just its existence in state. Confirm the variable/prop holding an error or failure message is actually referenced in the template output, and check whether it is delivered via an accessible status-message pattern (`aria-live`, `role="alert"`, or equivalent) — see `references/failure-state-and-accessibility.md` for that sub-review when it's in scope.
      7. **Flag any hand-rolled `fetch()` bypass.** If a custom `SubmitFunction` (or its returned callback) calls `fetch()` directly against a URL other than the form's own `action`, or reimplements submission without going through the form's native `action`/`method`, flag it for security review — this can bypass origin-check behavior SvelteKit applies to form-action submissions. Do not treat it as pure style.
      8. **Rank and report findings** per the output shape below.
      
      ## Decision tree
      
      - Public-facing, unauthenticated-reachable form (signup, contact, checkout, etc.) has no `method="POST"` and no resolvable action — submission is JS-only via a click handler → **HIGH, hard stop**. Zero-JS users cannot submit at all; this blocks approval for conversion-critical public forms specifically.
      - Same JS-only pattern on an internal/authenticated tool **that the user has explicitly confirmed is JS-required by design** → note as informational, not a finding; do not assume this exemption, ask for it.
      - Custom `SubmitFunction` returns a callback that does not branch on `result.type` (assumes success) → **HIGH**. Identify which of `failure`/`error`/`redirect` is unhandled and cite the exact missing branch.
      - `cancel()` called with no user-facing reason surfaced anywhere in the same code path → **HIGH** for a public-facing form, **MEDIUM** for an internal tool — silent cancellation is a UX dead end either way.
      - Native `<form method="POST">` with no `use:enhance` at all, and the fallback works correctly (submits, server redirects/re-renders with `form` prop on failure) → **not a finding**; this is the correct, working baseline.
      - Bare (no-argument) `use:enhance` on a form that would benefit from avoiding full-page reloads for inline validation UX, but the native fallback still works correctly → **LOW/informational** enhancement suggestion, not a defect.
      - Error/failure state exists in a variable but is never rendered in the template, or rendered without any accessible status-message association → **MEDIUM** (visual users can still see nothing) escalating to **HIGH** if the form is public-facing and conversion-critical.
      - Custom `SubmitFunction` or its callback calls `fetch()` directly instead of relying on native submission or `deserialize()`/`applyAction()` → **HIGH, flag for security review** (potential origin-check bypass), independent of whether error handling is otherwise correct.
      
      ## Adversarial checklist
      
      Before closing a review with no findings, confirm:
      
      - Does this form submit correctly via a plain HTTP POST with JavaScript entirely disabled — i.e., does it have a native `method="POST"` and a resolvable action, verified by reading the markup, not assumed?
      - Does every `use:enhance` customization branch on all `ActionResult` types it can realistically receive, or does it assume happy-path only?
      - Is every validation-triggered `cancel()` paired with a user-visible reason, not just a silent early return?
      - Would a screen-reader user actually be informed of a failed submission (rendered, accessibly-associated status message), or does the failure exist only as unread component state or a purely visual cue?
      - Did you flag every direct-`fetch()` bypass of native form submission for security review, even if its error handling looked otherwise correct?
      - Is a form flagged only for missing `use:enhance` when its native fallback in fact works fine? If so, that is a false positive — remove it; absence of `use:enhance` is not itself a defect.
      
      ## Output shape
      
      Every review response must include:
      
      1. **Scope** — forms and form actions reviewed, each labeled by native-fallback status (present/absent) and `use:enhance` usage category (absent / bare / custom-no-callback / custom-with-callback).
      2. **Findings** — ranked HIGH → MEDIUM → LOW, each with `file:line`, the classification (missing-fallback vs. unhandled-`ActionResult`-branch vs. silent-`cancel()` vs. unrendered/inaccessible failure state vs. fetch-bypass), and a concrete fix sketch matching the documented `use:enhance`/`applyAction`/`deserialize` patterns.
      3. **Evidence level** per finding: `repo evidence` (read the actual markup/action code) or `inference` (plausible but unverified, e.g., an action target that could not be statically resolved).
      4. **Verdict** — approve / approve-with-notes / block. Any public-facing, unauthenticated-reachable form with no native fallback is an automatic block, not a judgment call.
      5. **Open questions** — anything unverified, including whether an internal tool exempted from progressive enhancement was actually confirmed JS-required by the user rather than assumed.
      
  • metadata.json 1.2 KB
    {
      "id": "sveltekit-progressive-enhancement-review",
      "name": "SvelteKit Progressive Enhancement Review",
      "type": "skill",
      "provider": "frontend",
      "harnesses": [
        "claude-code",
        "cursor",
        "codex",
        "gemini",
        "kiro",
        "other"
      ],
      "summary": "Reviews SvelteKit forms and actions for functional resilience without JavaScript and for use:enhance error-handling correctness.",
      "source_type": "original",
      "official_docs": [
        "https://kit.svelte.dev/docs/form-actions",
        "https://svelte.dev/docs/kit/form-actions",
        "https://www.w3.org/WAI/WCAG22/quickref/",
        "https://owasp.org/www-project-top-ten/"
      ],
      "security_notes": "A custom use:enhance SubmitFunction that bypasses the form's native action/method to call a hand-rolled fetch() may skip SvelteKit's built-in CSRF-relevant origin checks applied to form actions — flag any such bypass for security review rather than treating it as a pure UX nit. Static-review-only skill: it reads and greps form/action source but never executes, builds, or runs application code.",
      "last_verified": "2026-07-02",
      "path": "skills/frontend/sveltekit-progressive-enhancement-review",
      "author": "github: VincentChuWaiChow",
      "version": "0.1.0"
    }
    
  • SKILL.md 7.9 KB
    ---
    name: sveltekit-progressive-enhancement-review
    description: Statically review SvelteKit forms and form actions for functional resilience without JavaScript (native method="POST" fallback) and for use:enhance customization correctness (ActionResult branch handling, cancel() feedback, redirect/invalidation behavior), flagging silent-failure and conversion-risk defects.
    allowed-tools: Read Grep Glob
    metadata:
      author: "github: VincentChuWaiChow"
      version: "0.1.0"
      updated: "2026-07-02"
      category: architecture
    ---
    
    # SvelteKit Progressive Enhancement Review
    
    ## Purpose
    
    Review SvelteKit forms and form actions for progressive-enhancement resilience — whether the form still functions via a native browser POST when JavaScript fails, is blocked, or hasn't finished loading — and for `use:enhance` customization correctness, without re-litigating server/client `load`-function placement, component styling, or routing precedence in every response. This skill exists because a form that "works fine" during manual testing with JavaScript enabled can still be a dead end for the measurable share of real users who hit slow/blocked/failed JS on real-world connections, and because a custom `use:enhance` `SubmitFunction` that only handles the happy path silently swallows every `failure`/`error`/`redirect` `ActionResult`, turning a broken submission into a UI that does nothing and tells the user nothing.
    
    ## When to use
    
    Use this skill when the user asks to:
    
    - review a new or changed `<form>` / form-action implementation before merge,
    - confirm whether a form "works without JavaScript",
    - investigate a report that a form submission silently does nothing (no error, no navigation, no feedback) when it fails,
    - audit a custom `use:enhance` `SubmitFunction` for missing `ActionResult` branches or unexplained `cancel()` calls.
    
    Do not use this skill for:
    
    - internal admin tools explicitly scoped as JS-required — progressive enhancement may be intentionally out of scope there; confirm that scoping with the user before flagging anything,
    - `+page.js` / `+page.server.js` / `+layout.js` universal-vs-server `load` placement review — use `sveltekit-routing-load-review` instead,
    - pure visual/styling review of form markup with no functional or error-handling question in scope.
    
    ## Context7 Documentation Protocol
    
    - Resolve the library ID with `resolve-library-id` (matched result: `/sveltejs/kit`) before citing any SvelteKit-specific claim about form actions or `use:enhance`.
    - Before asserting what the **default, no-argument** `use:enhance` provides, call `query-docs` against `/sveltejs/kit` for "progressive enhancement use:enhance" and quote the precise rule: `use:enhance` only applies to a `<form method="POST">` that posts to an action defined in `+page.server.js`; used without arguments it emulates native browser behavior — it updates the `form` prop and page status on success, resets the form element, calls `invalidateAll()`, and handles redirects, error boundaries, and focus management automatically, all without a full-page reload. Do not assume feature parity with a generic SPA form-handling library; this behavior is SvelteKit-specific and documented, not inferred.
    - Before asserting what a **custom** `SubmitFunction` must reimplement, call `query-docs` against `/sveltejs/kit` for "customising use:enhance SubmitFunction ActionResult" and confirm: the `SubmitFunction` receives `{ formElement, formData, action, cancel, submitter }` before submission, and may return an async callback receiving `{ result, update }` — where `result` is the `ActionResult` (`success` | `failure` | `redirect` | `error`) and `update` triggers the default post-submission logic that would otherwise run. If the callback is supplied at all, none of that default logic runs unless the callback calls `update()` or manually replicates it (e.g. via `applyAction(result)`).
    - Verify the SvelteKit version installed in the repo (`package.json`) before asserting `use:enhance` or `ActionResult` shape details are unchanged from the queried docs — form-action APIs have evolved across SvelteKit majors.
    - If Context7 is unavailable, fall back to the `official_docs` URLs in this skill's `metadata.json` and label the claim `documentation-based, unverified against current release`.
    - Never assume `applyAction` or `invalidateAll` is called inside a custom callback without reading the callback body — their absence is exactly the defect this skill exists to catch.
    
    ## Lean operating rules
    
    - First classify every `<form>` in scope as native-POST-capable (has `method="POST"` and a real action target resolving to a `+page.server.js` export) or JS-only (driven solely by a click/`onclick` handler with no native fallback) — do this by reading the markup, never by assuming.
    - A native `<form method="POST">` with **no** `use:enhance` at all already works without JavaScript by default; that is the baseline SvelteKit contract, not a defect. Do not flag its absence as a finding on its own.
    - Bare (no-argument) `use:enhance` gets the full documented default behavior (form reset, `invalidateAll`, redirect/error/focus handling) for free — do not demand the caller reimplement anything for a bare `use:enhance` usage.
    - Every custom `SubmitFunction` callback must branch on `result.type`. A callback that assumes `result` is always a success (e.g., only reads `result.data` with no type check) is a silent-failure defect: `failure`/`error`/`redirect` results are dropped on the floor and the user sees nothing.
    - A `cancel()` call inside the pre-submission `SubmitFunction` body must be paired with a clear, user-facing reason (e.g., inline client-side validation message shown to the user) — a silent `cancel()` with no visible feedback is equivalent to a silent failure.
    - Do not accept "an error variable exists in component state" as proof that failures are surfaced to the user. Trace whether that variable is actually rendered in the markup and, for accessibility, associated with the form via a status-message pattern (e.g., `aria-live` region or equivalent) — an unrendered or unannounced error state is still a silent failure for sighted users tracking visually and a silent failure for screen-reader users regardless.
    - Treat any custom `SubmitFunction` that bypasses the form's native `action`/`method` to call a hand-rolled `fetch()` directly (rather than letting `use:enhance` submit natively or using SvelteKit's own `deserialize()`/`applyAction()` pattern) as a security-review flag, not a pure UX nit — it can skip origin-check behavior SvelteKit applies to form-action submissions; do not wave it through as a stylistic preference.
    - Never execute, build, or run application code as part of this review; this is a static-review skill (Read/Grep/Glob only). "Works without JS" claims must be verified by reading markup for `method="POST"` and a resolvable action, never assumed from a component name or comment.
    
    ## References
    
    Load these only when needed:
    
    - [Review workflow and findings contract](references/workflow-and-output.md) — use for the step-by-step review procedure, the decision tree for classifying findings, and the required output shape.
    - [Failure-state and accessibility UX](references/failure-state-and-accessibility.md) — load only when reviewing how a failed/error/cancelled submission is surfaced to sighted and screen-reader users, not for pure native-fallback presence checks.
    
    ## Response minimum
    
    Return, at minimum:
    
    - the form(s) and form action(s) in scope,
    - evidence level (`repo evidence` from markup/action code vs `inference`) and Context7/docs grounding used,
    - ranked findings (file:line, missing-fallback or unhandled-`ActionResult`-branch gap, fix sketch matching documented `use:enhance`/`applyAction` patterns),
    - verdict on whether any public-facing, unauthenticated-reachable form (signup, contact, checkout) lacks a native fallback — this is a hard stop, not advisory,
    - open questions (e.g., whether an internal tool is confirmed JS-required by design before exempting it).
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related