Skip to content

feat(core): add correctness/checkable-bind-value rule - #306

Merged
oekazuma merged 10 commits into
mainfrom
worktree-checkable-bind-value
Jul 24, 2026
Merged

oekazuma merged 10 commits into
mainfrom
worktree-checkable-bind-value

Conversation

@oekazuma

@oekazuma oekazuma commented Jul 24, 2026 •

Copy link
Copy Markdown
Owner

Summary

  • Adds correctness/checkable-bind-value: flags <input type="checkbox" bind:value={x}> and <input type="radio" bind:value={x}> — bind:value binds the DOM value property, which checkbox/radio interaction never changes, so the bound state silently never updates in production.
  • Verified empirically against Svelte 5's own compiler first (per the issue's required first step): svelte.compile() reports zero warnings for this pattern, confirming it's a real deploy-blocker that only static analysis catches.
  • v1 scope: native <input> with a statically-literal type only. Dynamic type={expr}, <svelte:element>, <select bind:value>, and custom components accepting a bind:value-shaped prop are documented out-of-scope limitations.

Design doc: docs/superpowers/specs/2026-07-24-checkable-bind-value-design.md
Plan: docs/superpowers/plans/2026-07-24-checkable-bind-value.md

Closes #299

Test plan

  • pnpm --filter @svelte-vitals/core exec vitest run test/checkable-bind-value-parse.test.ts — 10/10 passing (detection logic + exclusions)
  • pnpm --filter @svelte-vitals/core exec vitest run test/checkable-bind-value-rule.test.ts — 5/5 passing (rule messages, severity, registration)
  • pnpm lint && pnpm typecheck && pnpm build && pnpm test && pnpm check:publish — all green (1569 tests passing across core/cli/mcp/vite)
  • Docs-links test passing (en/ja rule pages present)
  • Changeset added (minor bump, 4 packages)
  • Built via subagent-driven-development: 5 tasks, each independently reviewed (spec + quality) and approved, plus a final whole-branch review — ready to merge with no Critical/Important findings

🤖 Generated with Claude Code

Summary by CodeRabbit

  • New Features
    • Added the correctness/checkable-bind-value rule.
    • Warns when checkboxes or radio buttons use bind:value, which may not update after user interaction.
    • Recommends bind:checked for individual checkboxes and bind:group for checkbox or radio groups.
  • Documentation
    • Added English and Japanese guidance, examples, detection limitations, and configuration instructions.

oekazuma and others added 9 commits July 24, 2026 19:30
Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
…indValues

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
Also fixes two CLI test fixtures (malformed-svelte.test.ts,
suppression-e2e.test.ts) missing the checkableBindValues field on
ComponentFacts literals — a gap from an earlier task that only
surfaced under the monorepo-wide `pnpm typecheck`, not core's own
`tsc --noEmit`. Remaining diff is oxfmt reformatting picked up by
`pnpm format` while fixing the lint step.
@coderabbitai

coderabbitai Bot commented Jul 24, 2026 •

Copy link
Copy Markdown

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 9d126051-0f58-4a7a-965d-ad8622c80a46

📥 Commits

Reviewing files that changed from the base of the PR and between 559c0e1 and 5db213f.

📒 Files selected for processing (1)
  • docs/superpowers/plans/2026-07-24-checkable-bind-value.md
🚧 Files skipped from review as they are similar to previous changes (1)
  • docs/superpowers/plans/2026-07-24-checkable-bind-value.md

📝 Walkthrough

Walkthrough

Adds a correctness rule that detects static checkbox and radio inputs using bind:value, propagates findings through component facts, registers warnings with replacement guidance, and adds tests, documentation, planning artifacts, and a changeset.

Changes

Checkable bind value rule

Layer / File(s) Summary
Rule contract and facts model
docs/superpowers/specs/..., docs/superpowers/plans/..., packages/core/src/component.ts
Defines the rule scope, exclusions, diagnostics, detection approach, and ComponentFacts.checkableBindValues data shape.
Template detection and facts propagation
packages/core/src/component-parse.ts, packages/core/src/component-collect.ts, packages/core/test/*, packages/cli/test/*
Detects static native checkbox/radio bind:value directives, records their kind and line, supplies empty defaults, and updates parsing and fixture tests.
Rule implementation and registration
packages/core/src/rules/correctness/checkable-bind-value.ts, packages/core/src/rules/index.ts, packages/core/src/index.ts, packages/core/test/checkable-bind-value-rule.test.ts
Adds warning diagnostics with bind:checked and bind:group guidance, registers the rule, re-exports it, and tests its messages and severity.
Documentation and release metadata
docs/src/content/docs/rules/correctness/checkable-bind-value.md, docs/src/content/docs/ja/rules/correctness/checkable-bind-value.md, .changeset/checkable-bind-value-rule.md
Documents detection, exclusions, fixes, and disabling configuration, and declares minor releases for the affected packages.

Estimated code review effort: 3 (Moderate) | ~20 minutes

Sequence Diagram(s)

sequenceDiagram
  participant SvelteComponent
  participant ComponentParser
  participant ComponentFacts
  participant CorrectnessRule
  SvelteComponent->>ComponentParser: parse template AST
  ComponentParser->>ComponentFacts: record checkableBindValues
  ComponentFacts->>CorrectnessRule: provide component findings
  CorrectnessRule-->>SvelteComponent: emit warning and fix guidance
Loading

Possibly related PRs

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 75.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly names the new correctness/checkable-bind-value rule and matches the main change.
Linked Issues check ✅ Passed The PR implements the requested checkbox/radio bind:value rule, includes the stated fix guidance, static-scope limits, and warning severity.
Out of Scope Changes check ✅ Passed The added docs, tests, changeset, and support updates all relate directly to the new rule; no unrelated code changes stand out.

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 2

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/superpowers/plans/2026-07-24-checkable-bind-value.md`:
- Line 22: Update the working-directory instruction in the document to refer
generically to the repository root, removing the machine-specific absolute path
while preserving the command context.
- Around line 492-507: Fix the nested Markdown fences in the documented
examples, including the sections around the shown examples and the additional
affected ranges, so inner Svelte code blocks close with three backticks while
the surrounding four-backtick fence remains open. Ensure the outer fence closes
only after all examples, eliminating the downstream MD040 warnings.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro Plus

Run ID: 097f6126-16b8-43af-8a42-eb3dbf04e3da

📥 Commits

Reviewing files that changed from the base of the PR and between 9efe115 and 559c0e1.

📒 Files selected for processing (22)
  • .changeset/checkable-bind-value-rule.md
  • docs/src/content/docs/ja/rules/correctness/checkable-bind-value.md
  • docs/src/content/docs/rules/correctness/checkable-bind-value.md
  • docs/superpowers/plans/2026-07-24-checkable-bind-value.md
  • docs/superpowers/specs/2026-07-24-checkable-bind-value-design.md
  • packages/cli/test/malformed-svelte.test.ts
  • packages/cli/test/suppression-e2e.test.ts
  • packages/core/src/component-collect.ts
  • packages/core/src/component-parse.ts
  • packages/core/src/component.ts
  • packages/core/src/index.ts
  • packages/core/src/rules/correctness/checkable-bind-value.ts
  • packages/core/src/rules/index.ts
  • packages/core/test/architecture-rules.test.ts
  • packages/core/test/bundle-rules.test.ts
  • packages/core/test/checkable-bind-value-parse.test.ts
  • packages/core/test/checkable-bind-value-rule.test.ts
  • packages/core/test/component-collect.test.ts
  • packages/core/test/component-rule.test.ts
  • packages/core/test/correctness-rules.test.ts
  • packages/core/test/security-kit-rules.test.ts
  • packages/core/test/security-rules.test.ts

Comment thread docs/superpowers/plans/2026-07-24-checkable-bind-value.md Outdated
Comment thread docs/superpowers/plans/2026-07-24-checkable-bind-value.md Outdated
Remove a machine-specific absolute path from the working-directory note,
and fix nested Markdown fences in the Task 4 doc-page examples — the
inner ```svelte/```js examples were closing the outer four-backtick
wrapper early, which also swallowed the Japanese doc-page's frontmatter
into a stray fence further down. Verified with `pnpm exec oxfmt --check`.

Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
@oekazuma
oekazuma merged commit 15e0874 into main Jul 24, 2026
7 checks passed
@oekazuma
oekazuma deleted the worktree-checkable-bind-value branch July 24, 2026 13:03
oekazuma added a commit that referenced this pull request Jul 25, 2026
Resolves the conflicts with #306 (correctness/checkable-bind-value), which
landed on main while this branch was open. Every conflict was the same shape:
both rules add a fact to the component channel and a field to the same object
literals, so both sides are kept, with checkable-bind-value's entries first to
keep main's ordering stable.

- component.ts: both fact interfaces (CheckableBindValueFact, BasePathLinkFact)
  had been interleaved by the auto-merge — reconstructed as two complete
  interfaces, then both fields on ComponentFacts.
- component-parse.ts: same for the two collector functions, plus both
  collections wired into parseComponentFacts and both defaults in
  parseModuleFacts.
- The nine remaining files are one-line "both sides added a field" cases.

Verified: pnpm lint / typecheck / build / test all pass (1639 tests), and both
rules' facts are extracted side by side from one component.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
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.

feat(correctness): flag bind:value on checkbox/radio inputs (should be bind:checked / bind:group)

1 participant