Skip to content

[feat] Huge improvements: State-driven architecture, iterative stories, and automatic compaction#101

Open
Mandarinetto10 wants to merge 3 commits intosnarktank:mainfrom
Mandarinetto10:feat/state-driven-architecture
Open

[feat] Huge improvements: State-driven architecture, iterative stories, and automatic compaction#101
Mandarinetto10 wants to merge 3 commits intosnarktank:mainfrom
Mandarinetto10:feat/state-driven-architecture

Conversation

@Mandarinetto10
Copy link

Summary

This PR introduces a state-driven session management system, a four-layer memory model, iterative story support, and automatic progress compaction — addressing the key reliability and scalability issues that emerge when running Ralph on real-world projects with 10+ stories.

These changes are backwards-compatible: existing prd.json files work without modification, and the shell loop auto-bootstraps state.json on first run.

Motivation

After running Ralph extensively on production codebases, we encountered recurring failure modes that the original design doesn't handle:

  1. Session disorientation. Each session scans prd.json for the highest-priority incomplete story. When multiple stories exist at the same priority, or when a session fails mid-way, the next session may pick a different story or repeat work. There is no single source of truth for "what should I do next."

  2. Context exhaustion. progress.md (originally progress.txt) grows indefinitely. After 15-20 sessions, it fills the context window, leaving no room for actual implementation. There is no compaction mechanism.

  3. No multi-pass support. Some tasks (auditing N files, multi-pass refactors) inherently benefit from multiple sessions on the same story. The original design assumes one story = one session, with no way to express "repeat this story 5 times."

  4. Fragile completion detection. The original relies on the agent outputting <promise>COMPLETE</promise>, which is fragile — the agent might include it in explanatory text, or omit it due to context limits. ralph.sh already checks prd.json directly, making the text-based signal redundant.

  5. No guardrails. If the agent forgets to update state.json or commits without marking the story as passed, there's no feedback mechanism. Errors compound silently across sessions.

What changed

1. State-driven session management

New file: scripts/ralph/BOOTSTRAP.md

Each session now starts by reading state.json instead of scanning prd.json:

{
  "branch": "ralph/feature-name",
  "currentStory": "US-003",
  "storyTitle": "Add filter dropdown",
  "nextAction": "implement",
  "progressTokens": 2400,
  "compactionNeeded": false,
  "compactionThreshold": 10000,
  "lastUpdated": "2026-02-13"
}

Why this is better: The previous session explicitly tells the next session what to do. No ambiguity, no scanning, no race conditions. If state.json is missing (first run or corruption), BOOTSTRAP.md provides a deterministic recovery path. ralph.sh also auto-bootstraps state.json before the first session, so the agent doesn't waste context on bootstrap logic.

2. Four-layer memory model

The original has two memory layers (prd.json + progress.txt). This PR introduces a structured four-layer model:

Layer File Purpose Lifespan
Operational state.json Current story, next action, compaction status Per-session
Structural prd.json Story status, iteration counters, notes Per-PRD
Experiential progress.md Session logs, codebase patterns, learnings Per-PRD (auto-compacted)
Institutional CLAUDE.md Reusable conventions, gotchas Permanent (survives across PRDs)

Why this is better: Each layer has a clear purpose and lifespan. The Institutional Memory layer (a budgeted section at the bottom of CLAUDE.md) persists conventions and gotchas that survive across PRDs — something the original design loses every time you start a new feature.

3. Progressive disclosure

The original loads everything into every session. This PR splits the agent instructions into conditionally-loaded documents:

File Loaded when
BOOTSTRAP.md state.json missing (first run only)
COMPACTION.md state.json.compactionNeeded === true
ITERATIVE.md Current story has iterationMode field
PROGRESS-GUIDE.md Agent needs format reference for progress reports

Why this is better: A standard session loads only CLAUDE.md (or prompt.md for Amp) + state.json + partial progress.md + the relevant story from prd.json. The agent spends its context on implementation, not on instructions it doesn't need.

4. Automatic progress compaction

New file: scripts/ralph/COMPACTION.md

When progress.md exceeds the token threshold (~10,000 tokens), state.json flags compactionNeeded: true. The next session dedicates itself entirely to compaction using a three-zone approach:

  • Keep intact: Header + Codebase Patterns section (most valuable, always read first)
  • Keep intact: Last 3-4 session entries (most recent, likely still relevant)
  • Compact: Intermediate sessions to a minimal format (1 line per session)

Before compacting, the agent promotes any un-promoted learnings to the Codebase Patterns section, preventing knowledge loss.

Why this is better: The original has no compaction. After ~20 sessions, progress.md fills the context window and sessions start failing. The three-zone approach preserves the most useful information while reclaiming ~70% of tokens from intermediate sessions.

5. Iterative stories

New file: scripts/ralph/ITERATIVE.md

Stories can now declare iterationMode: "fixed" with a maxIterations count. One iteration = one session. The story is marked passes: true only when currentIteration >= maxIterations.

{
  "id": "US-003",
  "title": "Audit notification triggers",
  "iterationMode": "fixed",
  "maxIterations": 5,
  "currentIteration": 0,
  "passes": false
}

Why this is better: Multi-pass tasks like audits, batch refactors, and review passes benefit from fresh context across sessions. The original forces these into a single session (which runs out of context) or requires manual splitting into N identical stories.

Key design decisions:

  • Iterative mode is for batch work, not for oversized stories (those should be split)
  • Later iterations are encouraged to review earlier work, leveraging fresh context to catch mistakes
  • No-change iterations are valid outcomes (means earlier passes were thorough)
  • Quality check failures don't increment the counter — the next session retries the same iteration

6. Unified PRD skill

The original has two separate skills: skills/prd/SKILL.md (PRD generator) and skills/ralph/SKILL.md (JSON converter). This PR merges them into a single skills/ralph/SKILL.md that produces both outputs in one step:

  1. Human-readable PRD → tasks/prd-[feature-name].md
  2. Machine-readable JSON → scripts/ralph/prd.json

The unified skill also adds:

  • Iterative story support with schema documentation
  • Subagent usage guidance for implementation planning
  • Mandatory quality gates and browser verification criteria
  • Priority ordering guidance (dependency-first, then risk/complexity)
  • Archiving rules when switching between features
  • Comprehensive pre-save checklist (18 items)

7. Repository structure

All Ralph orchestration files moved from root to scripts/ralph/:

scripts/ralph/
├── BOOTSTRAP.md
├── CLAUDE.md
├── COMPACTION.md
├── ITERATIVE.md
├── PROGRESS-GUIDE.md
├── prompt.md
├── ralph.sh
└── prd.json.example

Root CLAUDE.md is now a slim pointer: When working on Ralph stories, read and follow scripts/ralph/CLAUDE.md.

Additional files:

  • .claudeignore: Excludes archives, binary files, build artifacts, and env files from Claude Code's context
  • .claude/settings.json: Two hooks (see Guardrails below)
  • .gitignore: Updated to track .claude/settings.json (shared hooks) while ignoring .claude/settings.local.json (personal settings)

Why this is better: Cleaner root directory. When users copy Ralph into their projects, they copy one directory (scripts/ralph/) instead of individual files scattered at root. The nested CLAUDE.md is automatically discovered by Claude Code alongside the root pointer.

8. Robust shell loop

ralph.sh improvements:

  • PRD schema validation at startup: checks for required fields (project, branchName, userStories) before spawning any sessions
  • Automatic state.json bootstrapping: creates state.json from prd.json before the first session, including iterative story detection
  • state.json integrity check after each session: warns (non-blocking) if required fields are missing
  • Debug mode (--debug): enables stream-json output format for Claude Code diagnostics
  • Automatic archiving now includes state.json alongside prd.json and progress.md
  • Completion detection via prd.json only (removed dependency on agent text output)
  • Terminology: iterationssessions (iterations now refers to the iterative story feature)

9. Claude Code hooks (guardrails)

New file: .claude/settings.json

Two hooks that provide automated feedback to the agent:

Hook Trigger Behavior
Commit warning git commit Non-blocking warning if the current story doesn't have passes: true yet
Session end gate Session stop Blocks session end if state.json.lastUpdated isn't today's date (ensures state is updated every session)

These are committed to the repo so they work out of the box for Claude Code users. Amp users are unaffected.

10. Mandatory knowledge promotion

Every session now includes a PROMOTE step: after writing learnings in progress.md, the agent must re-read them and promote anything useful beyond the current story to:

  • Codebase Patterns (top of progress.md) — survives compaction, read first every session
  • Institutional Memory (CLAUDE.md) or AGENTS.md — survives across PRDs

New file: scripts/ralph/PROGRESS-GUIDE.md — reference for progress report format and notes compaction rules.

Why this is better: In the original, valuable learnings buried in session logs are effectively lost after compaction or when starting a new PRD. The promotion step ensures important discoveries bubble up to persistent layers.

Migration

No migration needed. Existing prd.json files work as-is:

  1. ralph.sh auto-bootstraps state.json from prd.json on first run
  2. Stories without iterationMode are treated as standard (single-session) stories
  3. progress.md is initialized automatically if missing

The only user-facing change: files are now in scripts/ralph/ instead of root. Update your .gitignore paths accordingly.

Test plan

  • Fresh start: delete state.json and progress.md, run ralph.sh — verify auto-bootstrap creates both
  • Standard story: run a single-story PRD end-to-end, verify passes: true and state.json updated
  • Iterative story: run a 3-iteration story, verify currentIteration increments and passes only becomes true at iteration 3
  • Compaction: create a large progress.md (>10k tokens), set compactionNeeded: true in state.json, verify compaction session runs correctly
  • Branch switch: change branchName in prd.json, verify previous run is archived
  • Invalid PRD: remove userStories from prd.json, verify ralph.sh exits with error before spawning sessions
  • Claude Code hooks: commit without passes: true, verify warning appears; end session without updating state.json, verify session is blocked

Mandarinetto10 and others added 3 commits February 13, 2026 15:10
Introduce a robust session-oriented Ralph workflow: add BOOTSTRAP.md, COMPACTION.md, ITERATIVE.md, PROGRESS-GUIDE.md and an initial progress.md to define bootstrapping, compaction, iterative story rules, and progress report formats. Revise CLAUDE.md and README.md to use session/state.json + progress.md semantics and to document the iterative mode and institutional memory. Update prd.json.example to demonstrate an iterative story and validationCommand. Overhaul ralph.sh to use sessions (rename vars), add --debug, validate prd.json, archive runs, bootstrap and persist state.json, switch progress.txt → progress.md, support conditional Claude debug args, and detect completion by reading prd.json. Remove obsolete skills/prd SKILL.md and update skills/ralph SKILL.md. These changes formalize state handling, session lifecycle, compaction, and iteration rules for the autonomous agent loop.
Major changes:
- Move all Ralph orchestration files to scripts/ralph/ (preserves git history)
- Create slim root CLAUDE.md pointer to scripts/ralph/CLAUDE.md
- Update compactionThreshold from 7500 to 10000
- Improve COMPACTION.md with three-zone incremental compaction
- Expand Institutional Memory guidance with review & prune rules
- Update .gitignore to track .claude/settings.json (exclude only .local)
- Add .claudeignore for archives, flowchart, and build artifacts
- Update all path references across AGENTS.md, README.md, prompt.md, SKILL.md
- Add JSON schema validation to ralph.sh (PRD fields + state.json integrity)
- Add Claude Code hooks (post-commit warning + stop-time state.json check)

All 16 files modified/created per restructuring plan.
…ss.md

- Rewrite scripts/ralph/prompt.md to mirror CLAUDE.md's state-driven
  architecture (state.json orientation, iterative story support, PROMOTE
  step, State Update Rules, Critical Rules)
- Remove leftover progress.md from root (was from a previous Ralph run)

Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
Copilot AI review requested due to automatic review settings February 13, 2026 16:25
@greptile-apps
Copy link

greptile-apps bot commented Feb 13, 2026

Greptile Overview

Greptile Summary

This PR introduces a state-driven session management architecture for Ralph, replacing the previous scan-based story selection with an explicit state.json file that directs each session. The changes address session disorientation, context exhaustion, and lack of multi-pass support through a four-layer memory model (Operational, Structural, Experiential, Institutional) and automatic progress compaction.

Major improvements:

  • State-driven sessions: state.json eliminates ambiguity about which story to work on next, preventing race conditions when multiple stories share priority
  • Progressive disclosure: Instruction files are conditionally loaded (BOOTSTRAP.md, COMPACTION.md, ITERATIVE.md) to preserve context budget
  • Iterative stories: New iterationMode supports multi-pass tasks (audits, batch refactors) with predetermined iteration counts
  • Auto-compaction: When progress.md exceeds 10k tokens, a dedicated compaction session preserves patterns + recent entries while compressing intermediate logs
  • Unified skill: Merged prd + ralph skills into single workflow that generates both markdown PRD and prd.json
  • Repository restructure: All Ralph files moved to scripts/ralph/ for cleaner organization
  • Shell improvements: PRD schema validation, automatic state bootstrapping, state integrity checks, and debug mode
  • Claude Code hooks: Commit warnings and session-end state validation (requires Node.js)

Backwards compatibility: Existing prd.json files work without modification. Shell auto-bootstraps state.json on first run.

Key architectural insight: The previous design relied on agents scanning prd.json each session to find work, which is fragile. The new design uses explicit session handoff via state.json, where each session tells the next session exactly what to do. This eliminates ambiguity and enables features like iteration tracking and compaction coordination.

Minor notes:

  • validationCommand is mentioned in agent instructions but not executed by ralph.sh - relies on agent to run it
  • Claude Code hooks require Node.js runtime, will silently fail without it
  • Bootstrap jq query uses select(.passes == false) which may need null handling

Confidence Score: 4/5

  • This PR is safe to merge with minor considerations around environment dependencies
  • The architecture is well-designed and addresses real scalability issues. The implementation is solid with good error handling, validation, and backwards compatibility. Score is 4/5 (not 5) due to: (1) validationCommand documented but not enforced by shell, (2) hooks depend on Node.js availability which may not be universal, (3) minor jq edge case with null passes values. These are non-critical and can be addressed post-merge if issues arise in practice.
  • No files require special attention - the implementation is well-structured and consistent throughout

Important Files Changed

Filename Overview
scripts/ralph/ralph.sh Complete rewrite adds state.json bootstrapping, PRD validation, debug mode, and state integrity checks - well-structured with good error handling
scripts/ralph/CLAUDE.md New state-driven agent instructions with clear workflow, conditional loading strategy, and institutional memory - references validationCommand but shell doesn't implement it
scripts/ralph/BOOTSTRAP.md New bootstrap instructions for state.json creation on first run - clear, concise, matches shell implementation
scripts/ralph/ITERATIVE.md New comprehensive guide for iterative stories with clear rules on iteration counting, quality failures, and completion criteria
scripts/ralph/COMPACTION.md New progress compaction instructions with three-zone approach (keep header, keep patterns, keep recent, compact intermediate) - clear strategy
.claude/settings.json New hooks for commit warnings and session-end state checks - requires Node.js runtime, not validated in environments without Node
skills/ralph/SKILL.md Unified PRD skill merging generator + converter - comprehensive with iterative story support, but validationCommand schema conflicts with implementation

Sequence Diagram

sequenceDiagram
    participant Shell as ralph.sh
    participant State as state.json
    participant PRD as prd.json
    participant Agent as AI Agent
    participant Progress as progress.md
    participant Git as Git Repo

    Shell->>PRD: Validate schema (project, branchName, userStories)
    Shell->>State: Check if exists
    
    alt state.json missing (first run)
        Shell->>PRD: Query first story with passes==false
        Shell->>State: Bootstrap with currentStory, branch, nextAction
    end
    
    Shell->>Agent: Spawn session (pass CLAUDE.md or prompt.md)
    
    Agent->>State: Read currentStory, nextAction, compactionNeeded
    
    alt compactionNeeded==true
        Agent->>Progress: Read full file in chunks
        Agent->>Progress: Compact (keep patterns, keep recent, compress middle)
        Agent->>State: Set compactionNeeded=false
        Agent->>Git: Commit compaction
        Agent-->>Shell: End session
    else story has iterationMode
        Agent->>Agent: Load ITERATIVE.md (conditional)
        Agent->>PRD: Read current story acceptance criteria
        Agent->>Progress: Read Codebase Patterns + recent sessions
        Agent->>Agent: Implement iteration N
        Agent->>Agent: Run quality checks + validationCommand
        Agent->>Git: Commit changes (iteration N)
        Agent->>PRD: Increment currentIteration, set passes if currentIteration>=maxIterations
        Agent->>Progress: Append session report
        Agent->>State: Update to next story/iteration
        Agent-->>Shell: End session
    else standard story
        Agent->>PRD: Read current story acceptance criteria
        Agent->>Progress: Read Codebase Patterns + recent sessions
        Agent->>Agent: Implement story
        Agent->>Agent: Run quality checks
        Agent->>Git: Commit changes
        Agent->>PRD: Set passes=true
        Agent->>Progress: Append session report + promote learnings
        Agent->>State: Update to next story
        Agent-->>Shell: End session
    end
    
    Shell->>PRD: Check if all stories have passes==true
    
    alt All stories complete
        Shell->>Shell: Exit with success
    else More stories remain
        Shell->>State: Validate integrity (currentStory, lastUpdated, branch)
        Shell->>Agent: Spawn next session
    end
Loading

Last reviewed commit: f3c79a2

Copy link

@greptile-apps greptile-apps bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

19 files reviewed, 1 comment

Edit Code Review Agent Settings | Greptile

Comment on lines +115 to +116
FIRST_STORY_ID=$(jq -r '[.userStories[] | select(.passes == false)] | sort_by(.priority) | first | .id // empty' "$PRD_FILE")
FIRST_STORY_TITLE=$(jq -r '[.userStories[] | select(.passes == false)] | sort_by(.priority) | first | .title // empty' "$PRD_FILE")
Copy link

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Consider using select(.passes == false or .passes == null) to handle stories where the passes field might be missing

Note: If this suggestion doesn't match your team's coding style, reply to this and let me know. I'll remember it for next time!

Copy link

Copilot AI left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR restructures Ralph into a state-driven, session-oriented agent loop with progressive disclosure docs, iterative story support, and automatic progress log compaction—moving orchestration into scripts/ralph/ and consolidating PRD generation into a single /ralph skill.

Changes:

  • Introduces state.json-driven session management plus new guides for bootstrap, compaction, and iterative stories.
  • Replaces root-level Ralph assets with a scripts/ralph/ layout and updates README/agent pointers accordingly.
  • Adds Claude Code hooks and updates .gitignore/.claudeignore for the new workflow.

Reviewed changes

Copilot reviewed 18 out of 19 changed files in this pull request and generated 10 comments.

Show a summary per file
File Description
skills/ralph/SKILL.md Merges PRD generation + prd.json generation into one skill and documents iterative stories/archiving/checklists.
skills/prd/SKILL.md Removes the separate /prd skill in favor of the unified /ralph skill.
scripts/ralph/ralph.sh New loop script with PRD validation, state bootstrap, archiving/reset behavior, and debug mode.
scripts/ralph/prompt.md Updated Amp instructions for state-first workflow, compaction gating, and promotion rules.
scripts/ralph/prd.json.example Adds example schema including iterative story fields.
scripts/ralph/PROGRESS-GUIDE.md Defines progress log format, promotion rules, and notes compaction guidance.
scripts/ralph/ITERATIVE.md Defines iterative story semantics and PRD update rules per iteration/session.
scripts/ralph/COMPACTION.md Defines compaction-only session behavior and rewrite rules for progress.md.
scripts/ralph/CLAUDE.md Core Claude Code instructions updated for state-driven workflow and institutional memory section.
scripts/ralph/BOOTSTRAP.md Provides deterministic state bootstrap instructions when state.json is missing.
ralph.sh Removes the legacy root loop script.
prompt.md Removes the legacy root prompt template.
prd.json.example Removes the legacy root example PRD JSON.
README.md Updates install/workflow/docs to new session + state model and new file layout.
CLAUDE.md Replaces root instructions with a pointer to scripts/ralph/CLAUDE.md.
AGENTS.md Updates run commands and references to new Ralph file locations.
.gitignore Updates ignored working files to scripts/ralph/* and adds common build artifact ignores.
.claudeignore Adds ignore patterns for archives, binaries, build artifacts, env files, etc.
.claude/settings.json Adds Claude Code hooks for commit warning and session-stop gating.

💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment on lines +74 to +77
FOLDER_NAME=$(echo "$LAST_BRANCH" | sed 's|^ralph/||')
ARCHIVE_FOLDER="$ARCHIVE_DIR/$DATE-$FOLDER_NAME"

echo "Archiving previous run: $LAST_BRANCH"
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The archive folder name/message is derived from LAST_BRANCH, but the files being archived are the current working files. If prd.json has already been updated to the new branch, this will archive the new PRD under the old branch’s folder/name, which is misleading and can lead to the wrong run being preserved. Consider naming the archive folder from the branchName contained in the files you are copying (or store a snapshot of the previous PRD/branch separately) so the archive metadata matches the archived contents.

Suggested change
FOLDER_NAME=$(echo "$LAST_BRANCH" | sed 's|^ralph/||')
ARCHIVE_FOLDER="$ARCHIVE_DIR/$DATE-$FOLDER_NAME"
echo "Archiving previous run: $LAST_BRANCH"
# Use the branch name from the current PRD (CURRENT_BRANCH) for archive naming,
# so that the archive metadata matches the contents being copied.
FOLDER_NAME=$(echo "$CURRENT_BRANCH" | sed 's|^ralph/||')
ARCHIVE_FOLDER="$ARCHIVE_DIR/$DATE-$FOLDER_NAME"
echo "Archiving previous run (branch changed from $LAST_BRANCH to $CURRENT_BRANCH)"

Copilot uses AI. Check for mistakes.
echo " Created state.json: $FIRST_STORY_ID - $FIRST_STORY_TITLE"
fi
fi

Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The script only checks prd.json completion after spawning a tool session. If all stories are already passes: true, this still starts a session unnecessarily. Consider checking ALL_PASS once right after validating prd.json (before bootstrapping/running any tool) and exiting early to avoid wasted runs.

Suggested change
# Early exit if all stories already pass in prd.json
ALL_PASS=$(jq '[.userStories[].passes] | all' "$PRD_FILE" 2>/dev/null || echo "false")
if [ "$ALL_PASS" = "true" ]; then
echo "All user stories in prd.json already pass. No sessions needed."
exit 0
fi

Copilot uses AI. Check for mistakes.
Comment on lines +158 to +160
if [[ "$TOOL" == "amp" ]]; then
OUTPUT=$(cat "$SCRIPT_DIR/prompt.md" | amp --dangerously-allow-all 2>&1 | tee /dev/stderr) || true
else
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

OUTPUT=$(...) captures the full tool output into a shell variable, which can become extremely large (especially in --debug stream-json mode) and consume significant memory even though OUTPUT is no longer used for completion detection. Consider streaming directly to stderr via tee without storing in a variable (or only capturing when needed).

Copilot uses AI. Check for mistakes.
ITER_MODE=$(jq -r --arg id "$FIRST_STORY_ID" '[.userStories[] | select(.id == $id)] | first | .iterationMode // empty' "$PRD_FILE")
MAX_ITER=$(jq -r --arg id "$FIRST_STORY_ID" '[.userStories[] | select(.id == $id)] | first | .maxIterations // 0' "$PRD_FILE")

if [ -n "$ITER_MODE" ] && [ "$ITER_MODE" != "null" ]; then
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

For iterative stories, maxIterations defaults to 0 (.maxIterations // 0), which can produce nextAction like iteration 1/0 and hides invalid PRD input. Consider validating iterative story schema up-front (e.g., require maxIterations >= 1 and numeric currentIteration) and failing fast with a clear error if invalid.

Suggested change
if [ -n "$ITER_MODE" ] && [ "$ITER_MODE" != "null" ]; then
if [ -n "$ITER_MODE" ] && [ "$ITER_MODE" != "null" ]; then
# Validate that maxIterations is a positive integer for iterative stories.
if ! [[ "$MAX_ITER" =~ ^[0-9]+$ ]] || [ "$MAX_ITER" -lt 1 ]; then
echo "Error: invalid or missing maxIterations for iterative story '$FIRST_STORY_ID' in '$PRD_FILE' (got: '$MAX_ITER')." >&2
echo "Please ensure 'maxIterations' is a positive integer when 'iterationMode' is set." >&2
exit 1
fi

Copilot uses AI. Check for mistakes.
"hooks": [
{
"type": "command",
"command": "node -e \"const fs=require('fs');try{const s=JSON.parse(fs.readFileSync('scripts/ralph/state.json','utf8'));const today=new Date().toISOString().slice(0,10);if(s.lastUpdated!==today){console.log('state.json not updated today ('+s.lastUpdated+' vs '+today+')');process.exit(2)}}catch(e){}\""
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The Stop hook compares state.json.lastUpdated to new Date().toISOString().slice(0,10) (UTC date), while ralph.sh writes lastUpdated using local time (date +%Y-%m-%d). This can incorrectly block session stop around local/UTC midnight. Also, JSON/FS errors are silently ignored (catch(e){}), which means missing/corrupt state.json won’t block the stop as intended. Consider using local date in Node to match ralph.sh and exiting non-zero when state.json can’t be read/parsed.

Suggested change
"command": "node -e \"const fs=require('fs');try{const s=JSON.parse(fs.readFileSync('scripts/ralph/state.json','utf8'));const today=new Date().toISOString().slice(0,10);if(s.lastUpdated!==today){console.log('state.json not updated today ('+s.lastUpdated+' vs '+today+')');process.exit(2)}}catch(e){}\""
"command": "node -e \"const fs=require('fs');try{const s=JSON.parse(fs.readFileSync('scripts/ralph/state.json','utf8'));const d=new Date();const today=d.getFullYear()+'-'+String(d.getMonth()+1).padStart(2,'0')+'-'+String(d.getDate()).padStart(2,'0');if(s.lastUpdated!==today){console.log('state.json not updated today ('+s.lastUpdated+' vs '+today+')');process.exit(2)}}catch(e){console.error('Failed to read or parse scripts/ralph/state.json',e);process.exit(2);}\""

Copilot uses AI. Check for mistakes.
"Settings panel accessible from user menu",
"All preference fields rendered with correct input types",
"Save button persists changes to backend",
"Verify in browser: panel renders, fields are interactive, save works"
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In this example PRD, US-002 acceptance criteria omit a quality gate (e.g., “Typecheck passes” / “Tests pass”), but the skill guidance in skills/ralph/SKILL.md says every story should include at least one quality gate. Consider updating the example to match the documented rules so users don’t copy an invalid pattern.

Suggested change
"Verify in browser: panel renders, fields are interactive, save works"
"Verify in browser: panel renders, fields are interactive, save works",
"Tests pass"

Copilot uses AI. Check for mistakes.
Comment on lines +22 to +24
3. **Archive previous run** if `prd.json` already exists with a different `branchName` (see Archiving below)
4. Generate the PRD markdown file
5. Generate the `prd.json` file
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Step 3 says to archive the previous run if prd.json exists with a different branchName, but the canonical path elsewhere in this doc is scripts/ralph/prd.json. Consider updating this reference to avoid archiving/checking the wrong file location.

Suggested change
3. **Archive previous run** if `prd.json` already exists with a different `branchName` (see Archiving below)
4. Generate the PRD markdown file
5. Generate the `prd.json` file
3. **Archive previous run** if `scripts/ralph/prd.json` already exists with a different `branchName` (see Archiving below)
4. Generate the PRD markdown file
5. Generate the `scripts/ralph/prd.json` file

Copilot uses AI. Check for mistakes.
Comment on lines 122 to +126
Ralph will:
1. Create a feature branch (from PRD `branchName`)
2. Pick the highest priority story where `passes: false`
3. Implement that single story
4. Run quality checks (typecheck, tests)
5. Commit if checks pass
6. Update `prd.json` to mark story as `passes: true`
7. Append learnings to `progress.txt`
8. Repeat until all stories pass or max iterations reached
1. Read `state.json` for current story, branch, and next action
2. Create/checkout the feature branch (from `state.json`)
3. Pick the current story (from `state.json`, NOT by scanning prd.json)
4. Implement that single story (or one iteration of an iterative story)
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This workflow section refers to state.json, progress.md, and prd.json without the scripts/ralph/ prefix, but the rest of the README (and the repo layout) uses scripts/ralph/*. Consider making these paths explicit (e.g., scripts/ralph/state.json) so users don’t create/modify files in the repo root by mistake.

Copilot uses AI. Check for mistakes.
Comment on lines +151 to +154
| **Operational** | `state.json` | Current story, next action, branch, compaction status | Per-session (updated every session) |
| **Structural** | `prd.json` | Story status, iteration counters, notes | Per-PRD |
| **Experiential** | `progress.md` | Session logs, codebase patterns, learnings | Per-PRD, append-only (auto-compacted) |
| **Institutional** | `scripts/ralph/CLAUDE.md` | Reusable conventions, gotchas, cross-file dependencies | Permanent — survives across PRDs |
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

In the memory model table, Operational/Structural/Experiential layers list files as state.json / prd.json / progress.md, but the actual tracked locations are scripts/ralph/state.json, scripts/ralph/prd.json, and scripts/ralph/progress.md. Consider aligning these paths to match the new directory structure (and, if applicable, mention where Amp vs Claude store institutional memory).

Copilot uses AI. Check for mistakes.
- Memory persists via git history, `scripts/ralph/progress.md`, `scripts/ralph/prd.json`, and `scripts/ralph/state.json`
- Stories should be small enough to complete in one context window
- Always update AGENTS.md with discovered patterns for future iterations
- Always update Institutional Memory in scripts/ralph/CLAUDE.md with discovered patterns for future sessions
Copy link

Copilot AI Feb 13, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This document says to “Always update Institutional Memory in scripts/ralph/CLAUDE.md”, but the Amp prompt (scripts/ralph/prompt.md) instructs updating AGENTS.md files instead. Consider clarifying which file is the institutional memory source of truth per tool (Amp vs Claude) to avoid learnings being written to the wrong place.

Suggested change
- Always update Institutional Memory in scripts/ralph/CLAUDE.md with discovered patterns for future sessions
- Always update institutional memory in the appropriate file for the tool you're using:
- For Amp runs, update this `AGENTS.md` and `scripts/ralph/prompt.md` with discovered patterns for future sessions
- For Claude Code runs, update `scripts/ralph/CLAUDE.md` with discovered patterns for future sessions

Copilot uses AI. Check for mistakes.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant