literal
Comprehensive skill for the Literal Ruby gem (https://literal.fun) by Joel Drapper. Use when writing or reviewing Ruby code that uses Literal - typed properties via `prop`/`prop?`, runtime type matchers `_Array`/`_Union`/`_Map`/etc., structured objects (`Literal::Struct`, `Literal::Data`), value objects (`Literal::Value`, `Literal::Delegator`), enums (`Literal::Enum`), bitfield flags (`Literal::Flags`), generic collections (`Literal::Array(...)`, `Set`, `Hash`, `Tuple`), result monads (`Literal::Result`, `Success`, `Failure`), or JSON-style serialization. Also use when designing typed APIs in plain Ruby without external type checkers.
What this skill does
# Literal
Literal is a runtime type system for Ruby. It checks types when objects are constructed and when methods are called - no separate type checker needed. The library also provides building blocks for structured objects (Struct/Data), value objects, enums, flags, generic collections, and result monads.
The gemspec summary captures it: *"Enums, properties, generics, structured objects and runtime type checking."*
- Repo: https://github.com/joeldrapper/literal
- Docs: https://literal.fun
- License: MIT, requires Ruby >= 3.1
## How to use this skill
This skill is organised around the major user-facing features. The top-level features are listed below. When the user is working on a specific feature, load the matching reference file from `references/` for full details. Don't load every reference up-front - they're meant to be consulted as needed.
## Core idea: types are anything that responds to `===`
In Literal, a "type" is just anything that returns true/false from `===`. That includes:
- Plain Ruby classes (`String`, `Integer`, `MyClass`) - via `Module#===` (instance check)
- Ranges (`1..10`) - via `Range#===` (cover check)
- Regexps (`/foo/`) - via `Regexp#===` (match check)
- Procs/lambdas - via `Proc#===` (call check)
- Literal's own type matchers from `Literal::Types` (all prefixed with `_`)
- Any object you define with `===`
This is why every Literal API that accepts a "type" can also accept a primitive class or range.
## Top-level features (and which reference to load)
| Feature | What it is | Reference |
|---|---|---|
| Type matchers (`_Array`, `_Union`, `_Map`, `_Nilable`, `_Constraint`, ...) | The `_*` methods from `Literal::Types` for building runtime types | `references/types.md` |
| `prop` / `prop?` | Typed properties on any class via `extend Literal::Properties` | `references/properties.md` |
| `Literal::Struct` | Mutable structured object with `prop` (writers + readers public by default) | `references/struct-and-data.md` |
| `Literal::Data` | Frozen, immutable structured object with `prop` (reader-only) | `references/struct-and-data.md` |
| `Literal::Value(...)` | Typed value-object wrapper around a single value (e.g. `UserID = Literal::Value(Integer)`) | `references/value-and-delegator.md` |
| `Literal::Delegator(...)` | Typed delegator wrapping a value with full method delegation | `references/value-and-delegator.md` |
| `Literal::Enum(type)` | Closed set of typed members with predicates, indexing, ordering | `references/enum.md` |
| `Literal::Flags8/16/32/64` | Compact bitfield with named flags (boolean attributes) | `references/flags.md` |
| `Literal::Array/Set/Hash/Tuple` generics | Type-checked collection wrappers (`Literal::Array(String)`) | `references/collections.md` |
| `Literal::Result(success_t, failure_t)` | Result monad with `Success`/`Failure`, `try`, `and_then`, `also`, `handle` | `references/result.md` |
| `Literal::SerializationContext` + serializers | JSON-style serialize/deserialize driven by Literal types | `references/serialization.md` |
| `Literal.check`, `Literal.subtype?`, error messages | Programmatic type checking and subtype predicates | `references/runtime-checks.md` |
| Rails integration | `ActiveModel::Type` wrappers for enums and flags, `ActiveRecord::Relation(Model)` matcher | `references/rails.md` |
## Quick example
```ruby
require "literal"
class User < Literal::Data
# _Nilable, _Array, etc. are already available here:
# Literal::Data < Literal::DataStructure, which `extend`s Literal::Properties,
# which `include`s Literal::Types.
prop :id, Integer
prop :name, String
prop :email, _Nilable(String)
prop :tags, _Array(Symbol), default: -> { [] }
end
user = User.new(id: 1, name: "Alice", tags: [:admin])
# raises Literal::TypeError: id must be Integer, got "1"
User.new(id: "1", name: "Alice")
```
## Conventions Joel uses (from the project's AGENTS.md)
- Never use `is_a?` - prefer `===`, `in`, or `case`/`when`. Literal's whole API is built on `===`.
- Tests use a small custom `test do ... end` DSL (see the gem's `test/`); not RSpec or Minitest's `def test_*`.
## When NOT to use Literal
- You already have a Sorbet/RBS/Steep type system covering the codebase. Literal's runtime checks are duplicative there - though many people happily use both, since runtime checks catch what static checkers can't (e.g. unknown JSON shape).
- Hot inner loops where every method call goes through a type check. Literal is fast but not free; benchmark before adopting in tight loops.
## Reference index
- `references/types.md` - Every `_Type` matcher with examples
- `references/properties.md` - `prop`, `prop?`, kinds, defaults, coercion, predicates, writers, introspection
- `references/struct-and-data.md` - `Literal::Struct` vs `Literal::Data`, when to pick which
- `references/value-and-delegator.md` - `Literal::Value` and `Literal::Delegator` for value objects
- `references/enum.md` - `Literal::Enum` members, indexes, coercion, ordering
- `references/flags.md` - `Literal::Flags8/16/32/64` bitfields
- `references/collections.md` - `Literal::Array`, `Set`, `Hash`, `Tuple` generic collections
- `references/result.md` - `Literal::Result`, `Success`, `Failure`, `handle`, `try`, `and_then`
- `references/serialization.md` - `SerializationContext` and the built-in serializers
- `references/runtime-checks.md` - `Literal.check`, `Literal.subtype?`, type errors, `Brand`
- `references/rails.md` - Rails / ActiveModel / ActiveRecord integration
- `references/patterns.md` - Idioms and gotchas across the library
Related in Writing & Docs
jax-development
IncludedUse this skill when the user is writing, debugging, profiling, refactoring, reviewing, benchmarking, parallelising, exporting, or explaining JAX code, or when they mention JAX, jax.numpy, jit, grad, value_and_grad, vmap, scan, lax, random keys, pytrees, jax.Array, sharding, Mesh, PartitionSpec, NamedSharding, pmap, shard_map, Pallas, XLA, StableHLO, checkify, profiler, or the JAX repo. It helps turn NumPy or PyTorch-style code into pure functional JAX, fix tracer/control-flow/shape/PRNG bugs, remove recompiles and host-device syncs, choose transforms and sharding strategies, inspect jaxpr/lowering/IR, and benchmark compiled code correctly.
nature-article-writer
IncludedDrafts, rewrites, diagnostically critiques, and style-calibrates primary research manuscripts for Nature and Nature Portfolio journals. Use when the user wants a Nature-style title, summary paragraph or abstract, introduction, results, discussion, methods, figure legends, presubmission enquiry, cover letter, reviewer response, or when a scientific draft sounds generic, jargon-heavy, structurally weak, or AI-ish and needs precise, broad-reader-friendly prose without inventing data, analyses, or references. Best for primary research articles and letters rather than reviews or press releases unless explicitly adapting one.
deckrd
IncludedDocument-driven framework that derives requirements, specifications, implementation plans, and executable tasks from goals through structured AI dialogue. Use when user says "write requirements", "create spec", "plan implementation", "derive tasks", "structure this feature", "break down into tasks", or "document this module". Also use for reverse engineering existing code into docs (/deckrd rev). Do NOT use for direct code writing — use /deckrd-coder after tasks are generated. Do NOT use when the user only wants to run or fix existing code without planning.
clinical-decision-support
IncludedGenerate professional clinical decision support (CDS) documents for pharmaceutical and clinical research settings, including patient cohort analyses (biomarker-stratified with outcomes) and treatment recommendation reports (evidence-based guidelines with decision algorithms). Supports GRADE evidence grading, statistical analysis (hazard ratios, survival curves, waterfall plots), biomarker integration, and regulatory compliance. Outputs publication-ready LaTeX/PDF format optimized for drug development, clinical research, and evidence synthesis.
handling-sf-data
IncludedSalesforce data operations with 130-point scoring. Use this skill to create, update, delete, bulk import/export, generate test data, and clean up org records using sf CLI and anonymous Apex. TRIGGER when: user creates test data, performs bulk import/export, uses sf data CLI commands, needs data factory patterns for Apex tests, or needs to seed/clean records in a Salesforce org. DO NOT TRIGGER when: SOQL query writing only (use querying-soql), Apex test execution (use running-apex-tests), or metadata deployment (use deploying-metadata).
accelint-ac-to-playwright
IncludedConvert and validate acceptance criteria for Playwright test automation. Use when user asks to (1) review/evaluate/check if AC are ready for automation, (2) assess if AC can be converted as-is, (3) validate AC quality for Playwright, (4) turn AC into tests, (5) generate tests from acceptance criteria, (6) convert .md bullets or .feature Gherkin files to Playwright specs, (7) create test automation from requirements. Handles both bullet-style markdown and Gherkin syntax with JSON test plan generation and validation.