
List Builder
- 326 installs
- 133 repo stars
- Updated February 24, 2026
- jwynia/agent-skills
list-builder is an agent skill that converts rough requirements into prioritized, structured lists for backlogs, content plans, feature scopes, and launch checklists for developers who need ordered work items before comm
About
list-builder is a jwynia agent-skills utility that transforms unstructured notes or requests into prioritized, structured lists developers can execute against. It supports product backlogs, content plans, feature scopes, and launch checklists by ranking items, grouping related work, and clarifying sequencing before coding or publishing begins. Developers reach for list-builder when brainstorming produced too many ideas and a single ordered artifact is needed for sprint planning, content calendars, or release prep. The skill does not implement features—it produces planning lists that pair well with PRD or implementation skills downstream. It suits SaaS roadmaps, agent task queues, and content pipelines where priority and grouping reduce thrash. Prompt with constraints, deadlines, and audience so rankings reflect real tradeoffs rather than generic bullet dumps.
- Structured backlog lists
- Priority ordering
- Scope decomposition
- Checklist generation
- Requirement clarification
List Builder by the numbers
- 326 all-time installs (skills.sh)
- +6 installs in the week ending Aug 2, 2026 (Skillselion tracking)
- Ranked #850 of 3,282 Productivity & Planning skills by installs in the Skillselion catalog
- Data as of Aug 5, 2026 (Skillselion catalog sync)
npx skills add https://github.com/jwynia/agent-skills --skill list-builderAdd your badge
Show developers this skill is listed on Skillselion. Paste this into your README.
| Installs | 326 |
|---|---|
| repo stars | ★ 133 |
| Last updated | February 24, 2026 |
| Repository | jwynia/agent-skills ↗ |
How do you prioritize a backlog from rough requirements?
Turn rough requirements into prioritized, structured lists for backlogs, content plans, feature scopes, and launch checklists before committing build effort.
Who is it for?
Developers or PMs with messy requirements who need a ranked, structured list before sprint planning or build commits.
Skip if: Deep PRD authoring, automated test generation, or architecture design that needs diagrams and API contracts.
When should I use this skill?
The user has rough ideas and asks for a prioritized backlog, content plan, feature scope, or launch checklist.
What you get
Prioritized structured lists for backlogs, content plans, feature scopes, or launch checklists
- Prioritized backlog or checklist
- Structured scope list
Files
List Builder: Entropy List Curation Skill
You build comprehensive, high-quality lists for creative randomization. These lists feed into entropy tools that inject unpredictability into story development.
Core Principle
Good entropy lists have three properties: 1. Size — Large enough (50-200+ items) to feel genuinely random 2. Variety — Spans the full possibility space, not just obvious examples 3. Specificity — Concrete enough to spark ideas, not vague categories
LLMs are good at research, categorization, and quality control. Scripts are good at storage and random selection. This skill bridges them.
Dataset Maturity Levels
See references/dataset-quality-criteria.md for complete criteria.
| Level | Size | Status | Use Case |
|---|---|---|---|
| Starter | 10-30 | Quick example | Prototyping, demos |
| Functional | 30-75 | Usable but limited | Personal projects |
| Production | 75-150 | Ready for regular use | Client work, published tools |
| Comprehensive | 150+ | Reference quality | Definitive resource |
Key metrics:
- Size: Large enough for genuine randomness
- Variety: Covers all relevant dimensions (see criteria doc)
- Specificity: Concrete enough to spark ideas (20-60 char average)
- Freshness: >30% items that surprise (not first-thought)
Current built-in lists are Starter/Functional level. This skill exists to build them up to Production.
List Quality Criteria
What Makes a Good List Item
Good: "Elevator inspector" (specific, unexpected, sparks questions) Bad: "Office worker" (generic, expected, no hooks)
Good: "Self-storage facility at midnight" (specific time, atmosphere implied) Bad: "Building" (too vague to use)
Good: "They're solving a completely different case that uses same evidence" (specific collision mechanism) Bad: "They get in the way" (no mechanism, just effect)
Variety Dimensions
When building a list, ensure coverage across relevant dimensions:
Professions:
- Industries (medical, legal, construction, arts, service, tech)
- Status levels (entry-level to expert)
- Visibility (public-facing vs. behind-scenes)
- Unusual vs. common
- Historical vs. modern vs. emerging
Locations:
- Public vs. private
- Indoor vs. outdoor
- Urban vs. rural vs. suburban
- Time of day implications
- Emotional valence (creepy, mundane, sacred, liminal)
Character traits:
- Positive vs. negative vs. neutral
- Visible vs. hidden
- Self-aware vs. blind spots
- Stable vs. situational
Research Process
Step 1: Define the List
- What category of things?
- What will it be used for?
- What makes an item useful vs. useless?
- Target size (minimum 50, ideally 100+)
Step 2: Seed with Obvious Examples
Start with 10-20 items that come to mind immediately. These are the "available" options—the ones that would occur to anyone. They're valid but not sufficient.
Step 3: Research for Variety
Use available sources to expand beyond obvious:
Kiwix/Wikipedia:
- Category pages (e.g., "Category:Occupations")
- List articles (e.g., "List of unusual deaths")
- Related articles that branch into unexpected territory
Pattern: Dimensional expansion
- Pick a dimension the seed list lacks
- Research specifically in that dimension
- Add 10-20 items that fill the gap
Step 4: Filter for Quality
Remove items that are:
- Too vague to be useful
- Too similar to existing items
- Culturally specific without being interesting
- Requiring too much explanation
Step 5: Format for Use
Output as JSON array for use with entropy.ts:
{
"list_name": [
"Item one",
"Item two",
"Item three"
]
}Available Tools
validate-list.ts
Analyzes a list for quality and variety.
deno run --allow-read scripts/validate-list.ts list.json
# Check specific list in a file
deno run --allow-read scripts/validate-list.ts data.json professionsReports:
- Total count
- Duplicate check
- Average item length (too short = vague, too long = unwieldy)
- Variety assessment (if dimensions specified)
merge-lists.ts
Combines multiple list sources, deduplicates, and formats.
deno run --allow-read scripts/merge-lists.ts source1.json source2.json --output combined.jsonResearch Prompts
When you need to research a specific category, use prompts like:
For professions: "Find 20 professions in [industry] that most people don't know exist. Focus on jobs that involve interesting access, specialized knowledge, or unusual working conditions."
For locations: "Find 20 specific locations (not categories) where important conversations might happen. Focus on places with built-in tension, time pressure, or unexpected intimacy."
For character flaws: "Find 20 specific false beliefs people hold about themselves that aren't obvious villain traits. Focus on beliefs that feel protective but are actually limiting."
Example: Building a Professions List
Starting Seed (obvious)
- Doctor, lawyer, teacher, police officer, firefighter...
Dimensional Gap Analysis
- Missing: Niche technical jobs
- Missing: Service jobs with unusual access
- Missing: Jobs that involve secrets
- Missing: Jobs most people don't know exist
Research Expansion
Kiwix search: "List of occupations" → Category pages → specific unusual jobs
Add from research:
- Elevator inspector (access to buildings)
- Crime scene cleaner (aftermath, not crime)
- Ethical hacker (knows vulnerabilities)
- Cult deprogrammer (understands manipulation)
- Foley artist (creates reality from nothing)
- Patent examiner (sees innovations before public)
Quality Filter
Remove:
- "Businessperson" (too vague)
- "TikTok influencer" (too trendy, will date)
- "Alchemist" (wrong era unless fantasy)
Final Check
- 80+ items? ✓
- Multiple industries? ✓
- Mix of status levels? ✓
- Unexpected options? ✓
Integration with Entropy Tools
Lists built with this skill go into:
story-sense/data/for fiction-specific lists- Can be loaded via
entropy.ts --file
Naming convention:
[category]-[specificity].json- Examples:
professions-unusual.json,locations-liminal.json,objects-evidence.json
What You Do
1. Clarify what list is needed and how it will be used 2. Seed with obvious examples 3. Research to expand variety 4. Filter for quality 5. Format as JSON 6. Validate with tools 7. Document the list's intended use
What You Don't Do
- Generate random items (that's what the entropy script does)
- Create lists without research (leads to obvious-only items)
- Include items that require extensive explanation
- Prioritize quantity over quality (100 good items > 500 mediocre ones)
Output Persistence
This skill writes primary output to files so work persists across sessions.
Output Discovery
Before doing any other work:
1. Check for context/output-config.md in the project 2. If found, look for this skill's entry 3. If not found or no entry for this skill, ask the user first:
- "Where should I save output from this list-builder session?"
- Suggest:
data/orstory-sense/data/for entropy lists
4. Store the user's preference:
- In
context/output-config.mdif context network exists - In
.list-builder-output.mdat project root otherwise
Primary Output
For this skill, persist:
- The list itself - JSON format for entropy.ts use
- Research sources - where items came from
- Dimensional analysis - what variety dimensions are covered
- Usage documentation - what the list is for
Conversation vs. File
| Goes to File | Stays in Conversation |
|---|---|
| Final list (JSON) | Discussion of list purpose |
| Research sources | Iteration on items |
| Quality analysis | Real-time feedback |
| Documentation | Category refinement |
File Naming
Pattern: {category}-{specificity}.json Example: professions-unusual.json
Entropy Dataset Quality Criteria
This document defines what makes a randomization dataset production-ready vs. a quick starter example.
Maturity Levels
Level 1: Starter (10-30 items)
Status: Quick example, not production Use case: Demonstrating the concept, early prototyping
Characteristics:
- Obvious items that come to mind first
- Limited variety across dimensions
- May have gaps in coverage
- Sufficient for testing workflows
Upgrade path: Research to expand, analyze gaps, fill dimensions
---
Level 2: Functional (30-75 items)
Status: Usable but limited Use case: Personal projects, low-stakes ideation
Characteristics:
- Covers most obvious territory
- Some unexpected items mixed in
- May repeat patterns or clusters
- Repeated use will show limits
Upgrade path: Dimensional analysis, targeted research for gaps
---
Level 3: Production (75-150 items)
Status: Ready for regular use Use case: Client work, published tools, repeated application
Characteristics:
- Strong variety across all relevant dimensions
- Unexpected items outnumber obvious ones
- No significant gaps in coverage
- Can sustain repeated use without feeling stale
Upgrade path: Edge case research, user feedback integration
---
Level 4: Comprehensive (150+ items)
Status: Reference-quality dataset Use case: Definitive resource, high-frequency tools, teaching
Characteristics:
- Exhaustive coverage of possibility space
- Includes edge cases and rare examples
- Documented dimensions and coverage
- Can be subset for specific needs
Maintenance: Regular review for dated items, emerging categories
---
Quality Metrics
Size Thresholds
| Metric | Starter | Functional | Production | Comprehensive |
|---|---|---|---|---|
| Minimum items | 10 | 30 | 75 | 150 |
| Target items | 20 | 50 | 100 | 200+ |
| Unique items % | 90% | 95% | 99% | 100% |
Variety Score
Variety is measured across dimensions relevant to the list type.
Calculation: 1. Define 3-5 dimensions for the category 2. For each dimension, count how many distinct values appear 3. Variety score = average coverage across dimensions
Example for Professions:
- Industry dimension: 8 industries represented → good
- Status dimension: entry to expert → good
- Visibility dimension: all public-facing → gap
- Era dimension: all contemporary → may be intentional
Thresholds:
- Starter: May cluster in 1-2 dimensions
- Functional: Covers most dimensions partially
- Production: Good coverage across all dimensions
- Comprehensive: Full coverage including edge cases
Specificity Score
Items should be concrete enough to spark ideas.
Measurement:
- Average character length (target: 20-60 chars)
- Contains specific detail (place, time, condition)?
- Could generate a story question?
Examples by specificity:
| Too Vague | Good | Too Complex |
|---|---|---|
| "Building" | "Abandoned mall food court" | "The third floor conference room of the regional insurance claims processing center during the annual audit" |
| "Worker" | "Court stenographer" | "Person who operates the machine that tests tensile strength of aircraft cables" |
| "Problem" | "Ran out of time" | "Realized the evidence they needed was destroyed in exactly the way that would implicate them if discovered" |
Freshness Score
How many items would surprise someone familiar with the category?
Measurement:
- First-thought items (would come to most people): Should be < 30%
- Second-thought items (reasonable but less obvious): ~40%
- Surprising items (research-derived, unexpected): Should be > 30%
Test: Show 10 random items to someone unfamiliar. How many make them say "I wouldn't have thought of that"?
---
Dimensional Framework
Different list types have different relevant dimensions.
Professions
1. Industry: Medical, legal, construction, tech, arts, service, industrial, government 2. Status: Entry-level, skilled, professional, expert, leadership 3. Visibility: Public-facing, behind-scenes, hidden 4. Access: Physical access (buildings, systems), information access, social access 5. Rarity: Common knowledge vs. "jobs most people don't know exist"
Locations
1. Access: Public, semi-public, private, restricted 2. Setting: Urban, suburban, rural, wilderness, institutional 3. Time: Day vs. night vs. transitional implications 4. Atmosphere: Mundane, liminal, sacred, threatening, intimate 5. Permanence: Permanent structures, temporary, mobile
Character Traits/Flaws
1. Visibility: Obvious to others vs. hidden 2. Self-awareness: Character knows vs. blind spot 3. Origin: Innate vs. developed vs. reactive 4. Manifestation: Behavioral, emotional, cognitive, relational 5. Trajectory: Static vs. can arc
Objects
1. Size: Pocket, carried, furniture, vehicle, structure 2. Commonality: Universal, regional, professional, rare 3. Function: Tool, decoration, evidence, symbol 4. Material: Organic, manufactured, digital, ephemeral 5. Story potential: Can it be clue, weapon, macguffin, symbol?
---
Validation Checklist
Starter → Functional
- [ ] 30+ unique items
- [ ] No obvious duplicates
- [ ] At least 3 dimensions represented
- [ ] Some items that required research
Functional → Production
- [ ] 75+ unique items
- [ ] All relevant dimensions covered
- [ ] < 30% first-thought items
- [ ] > 30% research-derived items
- [ ] Average item length 20-60 characters
- [ ] Items can stand alone (no context required)
Production → Comprehensive
- [ ] 150+ unique items
- [ ] Edge cases included
- [ ] Documented dimensional coverage
- [ ] Tested with users/applications
- [ ] Dated items identified and flagged
- [ ] Expansion strategy documented
---
Maintenance Guidelines
Regular Review
- Quarterly: Check for dated references (trending terms, defunct companies)
- Annually: Reassess dimensional coverage against emerging categories
- On feedback: Track items that don't work in practice
Version Control
- Tag dataset versions
- Note what changed between versions
- Maintain changelog for significant updates
Documentation
Each production dataset should include:
- Purpose statement (what is this for?)
- Dimensional coverage map
- Known gaps (intentional exclusions)
- Last review date
- Expansion candidates (items to research)
---
Anti-Patterns
The Brainstorm Dump
50 items generated in one session without research. Problem: Clusters around first-thoughts, misses dimensions Fix: Research phase with intentional dimension-filling
The Wikipedia Copy
Entire category list pulled without curation. Problem: Includes unusable items, lacks quality control Fix: Filter for story utility, check each item
The Dated List
Items that made sense 5 years ago but now feel stale. Problem: "Instagram influencer" instead of timeless roles Fix: Prefer timeless over trendy; flag dated items for review
The Insider List
Items that only make sense with specialized knowledge. Problem: "FPGA verification engineer" means nothing to most writers Fix: Either explain in item or reserve for specialized lists
The Vague List
Items too general to spark specific ideas. Problem: "Professional" instead of "Forensic accountant" Fix: Add specificity: who, where, when, what condition?
#!/usr/bin/env -S deno run --allow-read
/**
* List Validator
*
* Analyzes entropy lists for quality metrics:
* - Size (is it large enough for good entropy?)
* - Duplicates (any repeated items?)
* - Item length (too short = vague, too long = unwieldy)
* - Variety indicators
*
* Usage:
* deno run --allow-read validate-list.ts list.json
* deno run --allow-read validate-list.ts data.json list_name
* deno run --allow-read validate-list.ts list.json --json
*/
type MaturityLevel = "starter" | "functional" | "production" | "comprehensive";
interface ValidationReport {
listName: string;
totalItems: number;
uniqueItems: number;
duplicates: string[];
avgLength: number;
minLength: number;
maxLength: number;
shortItems: string[]; // Items under 10 chars (likely too vague)
longItems: string[]; // Items over 100 chars (likely too complex)
specificityScore: number; // 0-100, based on length distribution
maturityLevel: MaturityLevel;
nextLevel: MaturityLevel | null;
itemsNeededForNext: number;
issues: string[];
suggestions: string[];
}
function validateList(items: string[], listName: string): ValidationReport {
// Find duplicates
const seen = new Set<string>();
const duplicates: string[] = [];
for (const item of items) {
const normalized = item.toLowerCase().trim();
if (seen.has(normalized)) {
duplicates.push(item);
}
seen.add(normalized);
}
// Calculate lengths
const lengths = items.map((i) => i.length);
const avgLength = lengths.reduce((a, b) => a + b, 0) / lengths.length;
const minLength = Math.min(...lengths);
const maxLength = Math.max(...lengths);
// Find problematic items
const shortItems = items.filter((i) => i.length < 10).slice(0, 5);
const longItems = items.filter((i) => i.length > 100).slice(0, 5);
// Specificity score (based on ideal length range 20-60)
const idealItems = items.filter((i) => i.length >= 20 && i.length <= 60).length;
const specificityScore = Math.round((idealItems / items.length) * 100);
// Maturity level assessment
const uniqueCount = seen.size;
let maturityLevel: MaturityLevel;
let nextLevel: MaturityLevel | null;
let itemsNeededForNext: number;
if (uniqueCount < 30) {
maturityLevel = "starter";
nextLevel = "functional";
itemsNeededForNext = 30 - uniqueCount;
} else if (uniqueCount < 75) {
maturityLevel = "functional";
nextLevel = "production";
itemsNeededForNext = 75 - uniqueCount;
} else if (uniqueCount < 150) {
maturityLevel = "production";
nextLevel = "comprehensive";
itemsNeededForNext = 150 - uniqueCount;
} else {
maturityLevel = "comprehensive";
nextLevel = null;
itemsNeededForNext = 0;
}
// Generate issues and suggestions
const issues: string[] = [];
const suggestions: string[] = [];
if (duplicates.length > 0) {
issues.push(`${duplicates.length} duplicate(s) found`);
suggestions.push("Remove duplicate entries");
}
if (maturityLevel === "starter") {
issues.push(`Starter level (${uniqueCount} items) - not production ready`);
suggestions.push(`Add ${itemsNeededForNext} more unique items to reach Functional level`);
} else if (maturityLevel === "functional") {
suggestions.push(`Add ${itemsNeededForNext} more items to reach Production level`);
}
if (specificityScore < 30) {
issues.push(`Low specificity score (${specificityScore}%) - items may be too vague or too complex`);
suggestions.push("Target item length of 20-60 characters for optimal specificity");
}
if (shortItems.length > items.length * 0.2) {
issues.push("Many items are very short (< 10 chars)");
suggestions.push("Short items may be too vague—add specificity");
}
if (longItems.length > items.length * 0.1) {
issues.push("Some items are very long (> 100 chars)");
suggestions.push("Long items may be unwieldy—consider splitting or simplifying");
}
if (avgLength < 15) {
issues.push("Average item length is short");
suggestions.push("Items may lack specificity needed to spark ideas");
}
return {
listName,
totalItems: items.length,
uniqueItems: seen.size,
duplicates,
avgLength: Math.round(avgLength * 10) / 10,
minLength,
maxLength,
shortItems,
longItems,
specificityScore,
maturityLevel,
nextLevel,
itemsNeededForNext,
issues,
suggestions,
};
}
function formatReport(report: ValidationReport): string {
const lines: string[] = [];
lines.push(`# List Validation: ${report.listName}\n`);
// Maturity level section
const maturityEmoji = {
comprehensive: "★",
production: "✓",
functional: "~",
starter: "⚠",
}[report.maturityLevel];
const maturityDesc = {
comprehensive: "Reference quality (150+)",
production: "Production ready (75-150)",
functional: "Usable but limited (30-75)",
starter: "Quick example only (< 30)",
}[report.maturityLevel];
lines.push("## Maturity Level");
lines.push(`${maturityEmoji} **${report.maturityLevel.toUpperCase()}** - ${maturityDesc}`);
lines.push(` ${report.uniqueItems} unique items`);
if (report.nextLevel) {
lines.push(` → ${report.itemsNeededForNext} more items needed for ${report.nextLevel}`);
}
if (report.duplicates.length > 0) {
lines.push(` ⚠ ${report.duplicates.length} duplicates found`);
}
lines.push("");
// Specificity section
const specEmoji = report.specificityScore >= 50 ? "✓" : report.specificityScore >= 30 ? "~" : "⚠";
lines.push("## Specificity");
lines.push(`${specEmoji} Score: ${report.specificityScore}% (items in ideal 20-60 char range)`);
lines.push(` Average length: ${report.avgLength} chars (range: ${report.minLength}-${report.maxLength})`);
if (report.shortItems.length > 0) {
lines.push(` Short items (< 10 chars): ${report.shortItems.slice(0, 3).join(", ")}${report.shortItems.length > 3 ? "..." : ""}`);
}
if (report.longItems.length > 0) {
lines.push(` Long items (> 100 chars): ${report.longItems.length} found`);
}
lines.push("");
// Issues
if (report.issues.length > 0) {
lines.push("## Issues");
for (const issue of report.issues) {
lines.push(`- ⚠ ${issue}`);
}
lines.push("");
}
// Suggestions
if (report.suggestions.length > 0) {
lines.push("## Suggestions");
for (const suggestion of report.suggestions) {
lines.push(`- ${suggestion}`);
}
lines.push("");
}
// Summary
if (report.issues.length === 0) {
lines.push("## Assessment");
lines.push("✓ List passes validation checks\n");
}
return lines.join("\n");
}
async function main(): Promise<void> {
const args = Deno.args;
if (args.includes("--help") || args.includes("-h")) {
console.log(`List Validator - Check entropy list quality
Usage:
deno run --allow-read validate-list.ts <file.json>
deno run --allow-read validate-list.ts <file.json> <list_name>
deno run --allow-read validate-list.ts <file.json> --json
If file contains a single array, validates that array.
If file contains an object with multiple lists, specify list_name or validate all.
Options:
--json Output as JSON
--all Validate all lists in file (default if no list_name given)
--help Show this help
`);
Deno.exit(0);
}
const jsonOutput = args.includes("--json");
const file = args.find((a) => a.endsWith(".json"));
const listName = args.find((a) => !a.startsWith("--") && !a.endsWith(".json"));
if (!file) {
console.error("Error: No JSON file specified");
Deno.exit(1);
}
let data: unknown;
try {
const text = await Deno.readTextFile(file);
data = JSON.parse(text);
} catch (e) {
console.error(`Error reading ${file}: ${e}`);
Deno.exit(1);
}
const reports: ValidationReport[] = [];
if (Array.isArray(data)) {
// Single array
reports.push(validateList(data as string[], file));
} else if (typeof data === "object" && data !== null) {
// Object with multiple lists
const obj = data as Record<string, string[]>;
if (listName) {
if (!obj[listName]) {
console.error(`Error: List "${listName}" not found in ${file}`);
console.error(`Available: ${Object.keys(obj).join(", ")}`);
Deno.exit(1);
}
reports.push(validateList(obj[listName], listName));
} else {
// Validate all
for (const [name, items] of Object.entries(obj)) {
if (Array.isArray(items)) {
reports.push(validateList(items, name));
}
}
}
} else {
console.error("Error: File must contain a JSON array or object");
Deno.exit(1);
}
if (jsonOutput) {
console.log(JSON.stringify(reports, null, 2));
} else {
for (const report of reports) {
console.log(formatReport(report));
if (reports.length > 1) {
console.log("---\n");
}
}
}
}
main();
Related skills
FAQ
What list types does list-builder create?
list-builder produces prioritized structured lists for product backlogs, content plans, feature scopes, and launch checklists. Supply rough requirements and constraints so the agent ranks and groups items meaningfully.
Does list-builder replace a PRD?
list-builder outputs ordered lists for planning, not full PRDs with metrics and stakeholder sections. Use a PRD skill when you need formal requirements documentation and list-builder when you need quick prioritization.