Important Notes
If something is unclear, use the AskUserTool to ask for clarification. Always use the generators of MCP tools if possible. The generators will create a file with the correct structure, and will help you avoid formatting errors. If you do not have a parameter for the generator, do not pass it as a parameter. The generator will create a reasonable default or TODO for someone else to fill out later. Do not delete TODO comments generated by the generator unless specifically instructed to do so. NEVER generate content, titles, links, or descriptions. Pass no value for those parameters, and the generator will create a TODO for someone else to fill out later.
Workflow
- Identify the event slug that you need to update.
- If the user did not provide an event slug, use the EventLookupTool to find the correct event.
- Determine if the update can be made with a generator. If so, use the appropriate generator to make the update. If not, make the update manually in the appropriate file.
- If you were unable to make the change with a generator or MCP, leave a comment in the PR description explaining why you were unable to use the generator or MCP.
- Each generator has a rubyevents MCP tool associated with it. You can use the MCP tools in place of the generators.
- Run
bin/rails validate:allto confirm that the structure of the file is correct. - Run
yerba applyto lint the yaml files. - Call
bin/rails db:seed:event_series[<event-series-slug>]to populate the database with the updated event data. - Start the dev server with
bin/devto review the changes locally. - Commit the changes.
- Take a screenshot with playwright of any pages that were affected by the update.
- Create a PR on the rubyevents/rubyevents repo using the .github/pull_request_template.md and include the screenshots in your PR description using the gh-image extension for GH.
Adding Event Data with the Generators
Adding a new Event
Events must be created first
Reference the documentation in docs/ADDING_EVENTS.md if needed.
Run bin/rails g event --help to review the available parameters for the EventGenerator.
Create a command to reproduce the event.
bin/rails g event --event-series ruby-community-conference --event ruby-community-conference-winter-edition-2026 --name "Ruby Community Conference Winter Edition 2026" --venue-name "TBD" --venue-address "TBD"
Adding a new CFP
Run bin/rails g cfp --help to review the available parameters for the CfpGenerator.
Create a command to reproduce the CFP.
bin/rails g cfp --event wnb-rb-meetup --name "WNB.rb Meetup Talk Proposal" --open-date "2026-08-17"
--link "https://docs.google.com/forms/d/e/1FAIpQLSdmOJxLdSdy74mXYxsr6ZRRhTN95Yxnq2B6n5mhUoGkVmDUGA/viewform"
If you create a CFP, capture a screenshot from http://localhost:3000/events//cfps after the changes are seeded.
Adding a talk
Review documentation in docs/ADDING_UNPUBLISHED_TALKS.md.
Run bin/rails g talk --help to review the available parameters for the TalkGenerator.
Create a command to reproduce the talk.
For example, if the user says "Create a lightning talk from Chris Hasiński, the title is Doom, and it's for the Ruby Community Conference".
bin/rails g talk --event ruby-community-conference-winter-edition-2026 --speaker "Chris Hasiński" --title "Doom" --kind lightning_talk
Call the generator once per talk, and do not attempt to create multiple talks in one command.
Do not pass --id when adding a new talk. Talk ids follow the "firstname-lastname-event-slug" convention (enforced by bin/rails validate:videos), and the generator derives the correct id from the speakers, kind, and title, avoiding ids already taken in the file. Only pass --id to update an existing talk: the generator updates the entry with that id, and fails with a list of available ids when it doesn't exist.
If you create talks, capture a screenshot from http://localhost:3000/events//talks after the changes are seeded.
Removing a talk
bin/rails validate:videos fails when a talk id disappears from a videos.yml, because a vanished id
is usually an unrecorded rename and production still knows the talk under the old id.
- Renamed? Keep the previous id on the renamed entry as
old_idso its record is migrated on the next seed.bin/rails talk_ids:backfill_old_idswrites it for you. - Removed on purpose? List the id under
removed_talk_idsin the event'sevent.yml(it lives there becausevideos.ymlhas a sequence root and cannot hold a top-level key):
# data/kaigi-on-rails/kaigi-on-rails-2026/event.yml
removed_talk_ids:
- "dave-thomas-kaigi-on-rails-2026"
Generating a Schedule
Load Documentation from docs/ADDING_SCHEDULES.md into context.
Call the help command and review the available parameters for the ScheduleGenerator.
bin/rails g schedule --help
Create a command to approximate the schedule provided by the user.
Modify the yaml file to match the schedule exactly.
If you create a schedule capture a screenshot from http://localhost:3000/events//schedule after the changes are seeded.
Generating a Sponsors file
Reference the documentation in docs/ADDING_SPONSORS.md if needed.
Run bin/rails g sponsors --help to review the available parameters for the SponsorsGenerator.
Create a command for each sponsor to add or update their details.
If you create a sponsor capture a screenshot from http://localhost:3000/events//sponsors after the changes are seeded.
Generate a Venue file
Review Documentation from docs/ADDING_VENUES.md.
Run bin/rails g venue --help to review the available parameters for the VenueGenerator.
Create a command to reproduce the venue.
bin/rails g venue --event "sfruby-2026" --name "SF Jazz" \
--address "201 Franklin Street San Francisco, CA 94102" \
--website "https://www.sfjazz.org/"
If you create a venue capture a screenshot from http://localhost:3000/events//venue after the changes are seeded.
Speakers
When updating speakers.yml, the structure is:
- name: "Speaker Name"
github: "github_handle"
slug: "speaker-name"
Other fields are permitted, but these are the fields I want you to focus on. The GitHub handle is how we deduplicate speakers, and populate their profile, so the key should always be present. These speakers are used for talks and involvements, so if a speaker is missing, you need to create a new record for them here.
Slug convention:
- Prefer the speaker's parameterized name as the slug (e.g.,
slug: "chris-hasinski"forname: "Chris Hasiński"). - If the name cannot be parameterized cleanly, use the speaker's GitHub handle as the slug (most common with Japanese names, eg. "河野十行", slug: "jugyo").
- Only transliterate when the speaker has no GitHub handle.
If the GitHub is unknown:
- name: "Speaker Name"
github: ""
slug: "speaker-name"
If the speaker has multiple aliases, they'll be included as aliases.
- name: "Speaker Name"
github: "github_handle"
slug: "speaker-name"
aliases:
- name: "Other Name"
slug: "other-name"
To update a speaker programmatically, use Static::SpeakersFile with a rails runner:
bin/rails runner 'file = Static::SpeakersFile.new; speaker = file.find_by(name: "Speaker Name"); speaker["github"] = "github-handle"; file.save!'