How Ralph's Priority Algorithm Selects the Next User Story
Ralph selects the next user story by filtering prd.json for unfinished stories where passes is false, sorting them by the numeric priority field in ascending order (lower numbers indicate higher priority), and returning the first item in that sorted list.
Ralph, an open-source autonomous development agent from the snarktank/ralph repository, uses a deterministic priority-based selection method to decide which feature to implement next. Understanding Ralph's priority algorithm for story selection is essential for teams structuring their Product Requirements Documents (PRDs) to ensure critical functionality gets built first.
How the Priority Algorithm Works
The algorithm follows a straightforward four-step process encoded in Ralph's core instructions:
- Load the PRD: Ralph reads
prd.json(or the JSON generated by the PRD skill) containing theuserStoriesarray. - Filter incomplete work: It filters the array to retain only entries where
"passes": false. - Sort by priority: It sorts the remaining stories by their
priorityvalue in ascending numerical order, where a lower integer represents higher business priority. - Select the winner: It returns the first story from the sorted results—the highest-priority unfinished item.
Handling Ties
When two stories share identical priority values, Ralph preserves JSON order and selects whichever appears first in the filtered list. This deterministic tie-breaker ensures consistent, repeatable behavior across iterations.
Source Code Implementation
The selection logic is explicitly defined in Ralph's instruction files rather than buried in complex code:
- In
prompt.md, the directive states: "Pick the highest priority user story wherepasses: false" (lines 10-11). - In
README.md, the workflow step reads: "Pick the highest priority story wherepasses: false" (lines 124-125).
These files demonstrate that Ralph treats story selection as a data-driven decision based strictly on the PRD's metadata fields, making the prd.json structure the single source of truth for work sequencing.
Practical Code Examples
You can replicate Ralph's selection logic locally to preview which story the agent will tackle next.
JavaScript Implementation
import { readFileSync } from 'fs';
// Load the PRD
const prd = JSON.parse(readFileSync('prd.json', 'utf-8'));
// Filter unfinished stories, sort by priority ascending, pick first
const nextStory = prd.userStories
.filter(story => story.passes === false)
.sort((a, b) => a.priority - b.priority)[0];
if (nextStory) {
console.log(`Next: ${nextStory.title} (Priority: ${nextStory.priority})`);
} else {
console.log('All stories have passed—Ralph is done!');
}
Bash and jq One-Liner
jq -r '
.userStories
| map(select(.passes == false))
| sort_by(.priority)
| .[0]
| "ID: \(.id)\nTitle: \(.title)\nPriority: \(.priority)"
' prd.json
Both snippets mirror the exact filter-then-sort-by-priority-ascending logic implemented in the snarktank/ralph source files.
Summary
- Ralph reads
prd.jsonto access theuserStoriesarray defined inprd.json.example. - Unfinished stories (where
passes: false) are candidates for selection. - The algorithm sorts by ascending priority values, meaning priority 1 outranks priority 5.
- The first item after sorting becomes the active development target.
- Ties defer to JSON document order for deterministic selection.
Frequently Asked Questions
Does Ralph support weighted priorities or MoSCoW classification?
No. According to the snarktank/ralph source code, Ralph expects simple numeric priorities where lower integers indicate higher urgency. The algorithm performs a basic ascending sort on the priority field without supporting textual classifications like "Must have" or "Should have."
What happens if all user stories have passes: true?
If every story in prd.json has "passes": true, the filter step returns an empty array. Ralph will have no candidate stories to sort or select, effectively signaling that the project is complete or awaiting new requirements in the PRD.
Can I use negative numbers or decimals for priority values?
The algorithm performs a numeric sort, so negative numbers and decimals are technically valid. However, Ralph's documentation in README.md suggests using positive integers starting from 1 for clarity, as this matches the standard convention referenced in the priority algorithm description.
Where is the selection logic actually executed?
While the algorithm is documented in prompt.md and README.md, the actual execution depends on the Amp AI tool processing these instructions. The logic is prompt-based rather than hardcoded in a specific function file, making the PRD structure itself the controlling authority for Ralph's workflow.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →