Extending Sheath
Conditional Static Analysis
Sheath follows Blade conditions to determine which markup can appear together when a template renders. This helps rules distinguish a real path-specific problem from markup that only looks incomplete when individual source lines are read in isolation. The analysis does not run application code.
#Conditions and Branches
Core rules correlate simple $flag, !$flag, and @unless($flag) predicates across separate blocks. They also account for nested conditions, loops, @forelse, switch branches, @break, and @continue when deciding whether two pieces of markup can appear on the same rendered path.
Unknown relationships remain unknown. A rule only treats a requirement as met when the source provides enough information for that rule to establish it. This is why two similar templates can produce different results when one uses a literal or repeated predicate and the other depends on an arbitrary expression.
#Attribute Resolution
Attribute order matters because Blade and HTML do not resolve every attribute source the same way.
- HTML attributes use the first effective value. A dynamic attribute provider before a known attribute can make the result unknown; the same provider after the known attribute cannot replace it.
- Component attribute data uses last-write behavior when a rule analyzes the compiled component values.
- Sheath understands known producers such as
@class,@style, and Blade's boolean attribute directives. Non-attribute directives such as@csrfand@methoddo not satisfy an attribute requirement. - Targeted Alpine and Livewire bindings affect only their named attribute. For example,
x-bind:aria-labelcan provide a dynamic accessible name, whilex-bind:classcannot. - A non-empty Alpine object binding such as
x-bind="bindings"can provide arbitrary attributes, so Sheath keeps the affected values unknown.
#Rendered Content and Captures
Non-empty x-text, x-html, and wire:text expressions can provide rendered text. Other reactive directives do not become content or an accessible name merely because they can change or reveal an element.
Non-output captures such as @push, @prepend, and a @section that is not closed with @show do not render at their definition site. A @section ... @show block does render in place. Sheath preserves that distinction when a rule checks ancestry or source order.
#Form Submission
A durable wire:submit listener or Alpine submit listener with .prevent replaces the browser's native form submission. .once, .passive, .outside, and .away do not provide the same guarantee, so form-method and CSRF rules do not treat them as equivalent.
#Autofix Safety
Conditional findings do not always have an automatic fix. Sheath offers a safe fix only when the resulting value is valid on every path changed by that edit. Use --dangerous only for fixes whose documented behavior matches the change you intend. See Automatic Fixing for the fix workflow.