Sorbet RBI Generation Skill
Generate Sorbet type signatures in separate .rbi files. RBI files are used when you cannot or should not modify the original Ruby source - such as for gems, generated code, or legacy codebases.
Instructions
When generating Sorbet RBI signatures, always follow these steps.
Copy this checklist and track your progress:
Sorbet RBI Generation Progress:
- [ ] Step 1: Analyze the Ruby source
- [ ] Step 2: Generate RBI files
- [ ] Step 3: Eliminate `T.untyped` in signatures
- [ ] Step 4: Review and refine signatures
- [ ] Step 5: Validate signatures with Sorbet
Rules
- You MUST NOT run Ruby code of the project.
- You MUST NOT use
T.untyped. Infer the proper type instead. - You MUST NOT use
T.unsafe- it bypasses type checking entirely. - You MUST NOT use
T.cast- it forces types without verification. - You MUST ask the user to provide more details if something is not clear.
- You MUST prepend any command with
bundle execif the project has Gemfile. - You MUST use
sig { }block syntax for method signatures. - You MUST add
extend T::Sigto classes/modules before usingsig. - You MUST NOT add method bodies in RBI files - only signatures and empty method definitions.
- You MUST place RBI files in
./rbidirectory.
1. Analyze the Ruby Source
Always perform this step.
Read and understand the Ruby source file:
- Identify all classes, modules, methods, constants and instance variables.
- Note inheritance, module inclusion and definitions based on metaprogramming.
- Note visibility modifiers -
public,private,protected. - Note type parameters for generic classes.
2. Generate RBI Files
Always perform this step.
-
Determine the correct RBI directory:
Place RBI files in
./rbidirectory. Sorbet reads all.rbifiles from this location.RBI files are needed to describe code Sorbet cannot understand statically:
- Gem definitions
- Methods created with
define_methodormethod_missing - Constants from
const_get/const_set - Dynamic ancestors added via
extend - DSL-generated methods (Rails, ActiveRecord, etc.)
-
Create the RBI file with typed sigil:
# typed: strict -
Add
extend T::Sigto each class/module:class MyClass extend T::Sig end -
Add method stubs with signatures (no method bodies):
Example - Ruby Source:
class User
attr_reader :name, :age
def initialize(name, age)
@name = name
@age = age
end
def greet(greeting)
"#{greeting}, #{@name}!"
end
end
Example - RBI File (rbi/user.rbi):
# typed: strict
class User
extend T::Sig
sig { returns(String) }
attr_reader :name
sig { returns(Integer) }
attr_reader :age
sig { params(name: String, age: Integer).void }
def initialize(name, age); end
sig { params(greeting: String).returns(String) }
def greet(greeting); end
end
- RBI files mirror structure but contain only signatures and empty method stubs
- See syntax.md for the full Sorbet RBI syntax guide
3. Eliminate T.untyped in Signatures
Always perform this step.
- Review all signatures and replace
T.untypedwith proper types. - Use code context, method calls, and tests to infer types.
- Use
T.untypedonly as a last resort when type cannot be determined.
4. Review and Refine Signatures
Always perform this step.
- Verify signatures are correct, coherent, and complete.
- Remove unnecessary
T.untypedtypes. - Ensure all methods and attributes have signatures.
- Verify class hierarchy and module inclusions match the source.
- Fix any errors and repeat until signatures are correct.
5. Validate Signatures with Sorbet
Always perform this step.
Run Sorbet type checker to validate signatures:
srb tc
Or with bundle:
bundle exec srb tc
This checks:
- Signature syntax correctness
- Type consistency
- Method parameter/return type matching
- Class/module structure matching source
Fix any errors reported and repeat until validation passes.
References
- syntax.md - Sorbet RBI syntax guide
- references/ - Real-world RBI examples from stripe-ruby
- Sorbet RBI documentation - Official RBI docs