Joel Drapper's wroclove.rb 2025 talk (first speaker of the day). Opens with a Shopify war story where interpolating a nil email into a Zendesk query caused 4,000–10,000 tickets to be deleted (a bug involving Puma, Rails, and a race condition that became a CVE in both) — framed as what runtime types would have prevented. Surveys existing static-typing efforts (Sorbet, RBS, Steep by Soutaro Matsumoto) and argues they don't fit Ruby's meta-programmed dynamism, require writing ~2× more code, and introduce more surface area for bugs. Defines a type as 'a description of a set of objects' and claims any Ruby object responding to `===` (triple-equals / case equality) is a type — classes, modules, ranges, regexes, procs, and even plain objects (as unit types). Notes that case/when, Enumerable#any?/all?, and pattern matching already use this interface. Introduces Literal, which exposes generics (Array, Tuple, Hash, Union, Intersection, Constraint, Interface, Deferred for recursive JSON), LiteralStruct/LiteralData (Ruby Struct/Data replacements taking typed `prop` declarations), Literal::Properties (to mix this into any class, e.g. a Phlex HTML Button component with union types for size/variant), Literal::Enum (constant enumerations with value/predicate/coerce methods), and Literal::Value/Decorator (wrapping a single value like UserID, delegating selected methods). Covers implementation details: nilable types are intentionally ugly; reserved keywords like `class` handled via binding.local_variable_get; code generation means near-zero runtime allocation overhead; primitive unions compile to set lookups (O(1)); types flatten; boot-time allocation is copy-on-write shared. Roadmap: literal array/tuple/hash/set collection objects that can't be corrupted post-initialization; subtype comparison between types (apple < fruit) to short-circuit collection operations (variance); cross-property validation via named block parameters; a result monad integrated with the type system; and LLM-schema generation/validation. Frames the approach as a Goldilocks solution — not full static safety, but composable runtime types, great error messages, compatible with metaprogramming, usable in 5 minutes, with Stephen's 'accordion of complexity' progression (Array → Array of User → can't push wrong → min 2 → name the concept 'group members'). Summary claim: Ruby has runtime types and always has — we just thought too narrowly. Q&A covers Literal vs dry-types (Literal uses `===`, dry puts coercion/default on the type — wrong place), production behavior (raises, but they saw fewer prod errors at Clear Scope), pattern-matching signatures at method boundaries, using Literal as a validation-library base (needs a non-raising `validate` path), writing types in separate files like RBS (not explored — fewer lines already), and observing production to auto-generate types (not a great idea — unions can't be inferred from observations, anomalies would create false types).