agentic-loop 3.4.7 → 3.5.2

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/ralph/ci.sh CHANGED
@@ -38,68 +38,227 @@ install_github_workflows() {
38
38
  # Create workflows directory
39
39
  mkdir -p .github/workflows
40
40
 
41
- # Copy workflow templates
42
- local template_dir="$RALPH_TEMPLATES/github/workflows"
43
-
44
- if [[ ! -d "$template_dir" ]]; then
45
- print_error "Workflow templates not found at $template_dir"
46
- return 1
47
- fi
41
+ # Read config values
42
+ local backend_dir frontend_dir test_cmd
43
+ backend_dir=$(get_config '.directories.backend' "")
44
+ frontend_dir=$(get_config '.directories.frontend' "")
45
+ test_cmd=$(get_config '.checks.testCommand' "")
48
46
 
49
- # Install PR workflow
47
+ # Generate PR workflow
50
48
  if [[ -f ".github/workflows/pr.yml" ]]; then
51
49
  echo " PR workflow already exists, skipping..."
52
50
  else
53
- cp "$template_dir/pr.yml" .github/workflows/pr.yml
51
+ generate_pr_workflow "$backend_dir" "$frontend_dir"
54
52
  print_success "Created .github/workflows/pr.yml (fast lint checks)"
55
53
  fi
56
54
 
57
- # Install nightly workflow
55
+ # Generate nightly workflow
58
56
  if [[ -f ".github/workflows/nightly.yml" ]]; then
59
57
  echo " Nightly workflow already exists, skipping..."
60
58
  else
61
- cp "$template_dir/nightly.yml" .github/workflows/nightly.yml
59
+ generate_nightly_workflow "$backend_dir" "$frontend_dir" "$test_cmd"
62
60
  print_success "Created .github/workflows/nightly.yml (full test suite)"
63
61
  fi
64
62
 
65
63
  echo ""
66
64
  echo "Workflows installed:"
67
65
  echo ""
68
- echo " 📋 PR Check (.github/workflows/pr.yml)"
66
+ echo " PR Check (.github/workflows/pr.yml)"
69
67
  echo " Runs on: Pull requests to main/master"
70
68
  echo " Checks: Lint, TypeScript, Build"
71
- echo " Speed: Fast (~1-2 min)"
72
69
  echo ""
73
- echo " 🌙 Nightly Tests (.github/workflows/nightly.yml)"
70
+ echo " Nightly Tests (.github/workflows/nightly.yml)"
74
71
  echo " Runs on: Daily at 3am UTC + manual trigger"
75
- echo " Checks: Full test suite + PRD testSteps + Coverage"
76
- echo " Speed: Comprehensive (~5-10 min)"
72
+ echo " Checks: Full test suite + PRD testSteps"
77
73
  echo ""
78
-
79
- # Check if we need to customize for monorepo
80
- local backend_dir frontend_dir
81
- backend_dir=$(get_config '.directories.backend' "")
82
- frontend_dir=$(get_config '.directories.frontend' "")
83
-
84
- if [[ -n "$backend_dir" ]] || [[ -n "$frontend_dir" ]]; then
85
- print_warning "Monorepo detected. You may need to customize workflow paths."
86
- echo ""
87
- echo " Edit .github/workflows/*.yml to add:"
88
- [[ -n "$backend_dir" ]] && echo " - working-directory: $backend_dir"
89
- [[ -n "$frontend_dir" ]] && echo " - working-directory: $frontend_dir"
90
- echo ""
91
- fi
92
-
93
- # Remind about secrets
94
74
  echo "Next steps:"
95
75
  echo " 1. Review and customize the workflows if needed"
96
- echo " 2. Commit and push: git add .github && git commit -m 'ci: Add GitHub Actions workflows'"
97
- echo " 3. Set up any required secrets in GitHub repo settings"
76
+ echo " 2. Commit: git add .github && git commit -m 'ci: Add workflows'"
77
+ echo " 3. Add any required secrets in GitHub repo settings"
98
78
  echo ""
99
79
 
100
80
  return 0
101
81
  }
102
82
 
83
+ # Generate PR workflow based on project structure
84
+ generate_pr_workflow() {
85
+ local backend_dir="$1"
86
+ local frontend_dir="$2"
87
+
88
+ cat > .github/workflows/pr.yml << 'HEADER'
89
+ # Fast PR checks - lint only, no tests
90
+ name: PR Check
91
+
92
+ on:
93
+ pull_request:
94
+ branches: [main, master]
95
+
96
+ jobs:
97
+ lint:
98
+ runs-on: ubuntu-latest
99
+ steps:
100
+ - uses: actions/checkout@v4
101
+ HEADER
102
+
103
+ # Detect and add Python steps
104
+ if [[ -f "pyproject.toml" ]] || [[ -f "requirements.txt" ]] || [[ -n "$backend_dir" && -f "$backend_dir/pyproject.toml" ]]; then
105
+ local py_dir="${backend_dir:-.}"
106
+ cat >> .github/workflows/pr.yml << EOF
107
+
108
+ - name: Set up Python
109
+ uses: actions/setup-python@v5
110
+ with:
111
+ python-version: '3.11'
112
+
113
+ - name: Install Python dependencies
114
+ run: |
115
+ pip install ruff uv
116
+ cd $py_dir && uv pip install -e . --system 2>/dev/null || pip install -e . 2>/dev/null || true
117
+
118
+ - name: Ruff lint
119
+ run: cd $py_dir && ruff check .
120
+ EOF
121
+ fi
122
+
123
+ # Detect and add Node.js steps
124
+ if [[ -f "package.json" ]] || [[ -n "$frontend_dir" && -f "$frontend_dir/package.json" ]]; then
125
+ local node_dir="${frontend_dir:-.}"
126
+ cat >> .github/workflows/pr.yml << EOF
127
+
128
+ - name: Set up Node.js
129
+ uses: actions/setup-node@v4
130
+ with:
131
+ node-version: '20'
132
+
133
+ - name: Install Node dependencies
134
+ run: cd $node_dir && npm ci
135
+
136
+ - name: Lint
137
+ run: cd $node_dir && npm run lint 2>/dev/null || true
138
+
139
+ - name: TypeScript check
140
+ run: cd $node_dir && npx tsc --noEmit 2>/dev/null || true
141
+
142
+ - name: Build
143
+ run: cd $node_dir && npm run build 2>/dev/null || true
144
+ EOF
145
+ fi
146
+ }
147
+
148
+ # Generate nightly workflow based on project structure
149
+ generate_nightly_workflow() {
150
+ local backend_dir="$1"
151
+ local frontend_dir="$2"
152
+ local test_cmd="$3"
153
+
154
+ cat > .github/workflows/nightly.yml << 'HEADER'
155
+ # Nightly comprehensive test suite
156
+ name: Nightly Tests
157
+
158
+ on:
159
+ schedule:
160
+ - cron: '0 3 * * *' # 3am UTC daily
161
+ workflow_dispatch:
162
+
163
+ jobs:
164
+ test:
165
+ runs-on: ubuntu-latest
166
+ HEADER
167
+
168
+ # Add services if backend exists (likely needs DB)
169
+ if [[ -n "$backend_dir" ]] || [[ -f "pyproject.toml" ]]; then
170
+ cat >> .github/workflows/nightly.yml << 'EOF'
171
+
172
+ services:
173
+ postgres:
174
+ image: postgres:15
175
+ env:
176
+ POSTGRES_USER: test
177
+ POSTGRES_PASSWORD: test
178
+ POSTGRES_DB: test
179
+ ports:
180
+ - 5432:5432
181
+ options: >-
182
+ --health-cmd pg_isready
183
+ --health-interval 10s
184
+ --health-timeout 5s
185
+ --health-retries 5
186
+
187
+ env:
188
+ DATABASE_URL: postgresql://test:test@localhost:5432/test
189
+ EOF
190
+ fi
191
+
192
+ cat >> .github/workflows/nightly.yml << 'EOF'
193
+
194
+ steps:
195
+ - uses: actions/checkout@v4
196
+ EOF
197
+
198
+ # Add Python setup and tests
199
+ if [[ -f "pyproject.toml" ]] || [[ -n "$backend_dir" && -f "$backend_dir/pyproject.toml" ]]; then
200
+ local py_dir="${backend_dir:-.}"
201
+ local py_test_cmd="${test_cmd:-pytest -v --tb=short}"
202
+
203
+ cat >> .github/workflows/nightly.yml << EOF
204
+
205
+ - name: Set up Python
206
+ uses: actions/setup-python@v5
207
+ with:
208
+ python-version: '3.11'
209
+
210
+ - name: Install Python dependencies
211
+ run: |
212
+ pip install uv
213
+ cd $py_dir && uv pip install -e ".[dev]" --system 2>/dev/null || pip install -e . 2>/dev/null || true
214
+
215
+ - name: Run migrations
216
+ run: cd $py_dir && alembic upgrade head 2>/dev/null || true
217
+ continue-on-error: true
218
+
219
+ - name: Python tests
220
+ run: cd $py_dir && $py_test_cmd
221
+ continue-on-error: true
222
+ EOF
223
+ fi
224
+
225
+ # Add Node.js setup and tests
226
+ if [[ -f "package.json" ]] || [[ -n "$frontend_dir" && -f "$frontend_dir/package.json" ]]; then
227
+ local node_dir="${frontend_dir:-.}"
228
+ cat >> .github/workflows/nightly.yml << EOF
229
+
230
+ - name: Set up Node.js
231
+ uses: actions/setup-node@v4
232
+ with:
233
+ node-version: '20'
234
+
235
+ - name: Install Node dependencies
236
+ run: cd $node_dir && npm ci
237
+
238
+ - name: Node tests
239
+ run: cd $node_dir && npm test 2>/dev/null || true
240
+ continue-on-error: true
241
+ EOF
242
+ fi
243
+
244
+ # Add PRD tests
245
+ cat >> .github/workflows/nightly.yml << 'EOF'
246
+
247
+ - name: Run PRD tests
248
+ if: hashFiles('.ralph/prd.json') != ''
249
+ run: npx agentic-loop test prd 2>/dev/null || true
250
+ continue-on-error: true
251
+
252
+ notify:
253
+ needs: test
254
+ runs-on: ubuntu-latest
255
+ if: failure()
256
+ steps:
257
+ - name: Notify on failure
258
+ run: echo "Nightly tests failed!"
259
+ EOF
260
+ }
261
+
103
262
  check_ci_status() {
104
263
  echo ""
105
264
  print_info "=== CI/CD Status ==="
@@ -1,10 +1,9 @@
1
1
  #!/usr/bin/env bash
2
- # protect-prd.sh - Protect prd.json from accidental edits
2
+ # protect-prd.sh - Protect prd.json from marking stories as passed
3
3
  # Hook: PreToolUse matcher: "Edit|Write"
4
4
  #
5
- # Allows: /prd, /idea commands (they create .prd-edit-allowed marker)
6
- # Allows: Ralph loop fixing test steps (detected by last_failure.txt)
7
- # Blocks: Accidental edits during normal coding
5
+ # Allows: Most edits to prd.json (adding fields, fixing test steps, etc.)
6
+ # Blocks: Edits that mark stories as "passes": true (Ralph handles this)
8
7
 
9
8
  set -euo pipefail
10
9
 
@@ -13,25 +12,18 @@ FILE_PATH=$(echo "$INPUT" | jq -r '.tool_input.file_path // .tool_input.path //
13
12
 
14
13
  # Check if editing prd.json
15
14
  if [[ "$FILE_PATH" == *"prd.json"* ]]; then
16
- # Allow if /prd or /idea set the bypass marker
17
- if [[ -f ".ralph/.prd-edit-allowed" ]]; then
18
- rm -f ".ralph/.prd-edit-allowed" # One-time use
19
- echo '{"continue": true}'
20
- exit 0
21
- fi
15
+ # Get the new content being written
16
+ NEW_STRING=$(echo "$INPUT" | jq -r '.tool_input.new_string // .tool_input.content // ""')
22
17
 
23
- # Allow if Ralph is in a retry loop with a RECENT failure (within 10 min)
24
- # This lets Ralph fix broken test steps, but not stale failures from old sessions
25
- if [[ -f ".ralph/last_failure.txt" ]]; then
26
- file_age=$(( $(date +%s) - $(stat -f %m ".ralph/last_failure.txt" 2>/dev/null || echo 0) ))
27
- if [[ $file_age -lt 600 ]]; then # 10 minutes
28
- echo '{"continue": true}'
29
- exit 0
30
- fi
18
+ # Block if trying to set passes to true (Ralph handles story completion)
19
+ if echo "$NEW_STRING" | grep -qE '"passes"\s*:\s*true'; then
20
+ echo "BLOCKED: Cannot mark stories as passed. Ralph handles this after verification." >&2
21
+ exit 2 # Exit code 2 = blocking error
31
22
  fi
32
23
 
33
- echo "BLOCKED: prd.json is managed by Ralph. Use /prd or /idea to add stories." >&2
34
- exit 2 # Exit code 2 = blocking error
24
+ # Allow all other prd.json edits (adding mcp, originalContext, fixing testSteps, etc.)
25
+ echo '{"continue": true}'
26
+ exit 0
35
27
  fi
36
28
 
37
29
  # Allow all other edits
package/ralph/loop.sh CHANGED
@@ -504,135 +504,11 @@ startup_checklist() {
504
504
  fi
505
505
  }
506
506
 
507
- # Helper: Inject story details into prompt
508
- _inject_story_context() {
509
- local story_json="$1"
510
-
511
- echo ""
512
- echo "---"
513
- echo ""
514
- echo "## Current Story"
515
- echo ""
516
- echo '```json'
517
- echo "$story_json"
518
- echo '```'
519
- }
520
-
521
- # Helper: Inject file guidance into prompt
522
- _inject_file_guidance() {
523
- local story_json="$1"
524
-
525
- local has_files
526
- has_files=$(echo "$story_json" | jq -r '.files // empty' 2>/dev/null)
527
- [[ -z "$has_files" ]] && return
528
-
529
- echo ""
530
- echo "### File Guidance for This Story"
531
- echo ""
532
- echo "**Create these files:**"
533
- echo "$story_json" | jq -r '.files.create[]? // empty' | sed 's/^/- /'
534
- echo ""
535
- echo "**Modify these files:**"
536
- echo "$story_json" | jq -r '.files.modify[]? // empty' | sed 's/^/- /'
537
- echo ""
538
- echo "**Reuse/import from:**"
539
- echo "$story_json" | jq -r '.files.reuse[]? // empty' | sed 's/^/- /'
540
- }
541
-
542
- # Helper: Inject scalability guidance for story
543
- _inject_story_scale() {
544
- local story_json="$1"
545
-
546
- local has_scale
547
- has_scale=$(echo "$story_json" | jq -r '.scale // empty' 2>/dev/null)
548
- [[ -z "$has_scale" ]] && return
549
-
550
- echo ""
551
- echo "### Scalability Requirements for This Story"
552
- echo ""
553
- echo "$story_json" | jq -r '.scale | to_entries[] | "- **\(.key):** \(.value)"' 2>/dev/null
554
- }
555
-
556
- # Helper: Inject styleguide reference for frontend stories
557
- _inject_styleguide() {
558
- local story_json="$1"
559
-
560
- local story_type
561
- story_type=$(echo "$story_json" | jq -r '.type // "frontend"' 2>/dev/null)
562
- local styleguide_path
563
- styleguide_path=$(get_config '.styleguide' "")
564
-
565
- if [[ "$story_type" == "frontend" && -n "$styleguide_path" && -f "$styleguide_path" ]]; then
566
- echo ""
567
- echo "### Styleguide"
568
- echo ""
569
- echo "**FIRST:** Read the project styleguide at \`$styleguide_path\` before implementing."
570
- echo "Use existing components, colors, and patterns from the styleguide."
571
- fi
572
- }
573
-
574
- # Helper: Inject feature-level context
575
- _inject_feature_context() {
576
- echo ""
577
- echo "## Feature Context"
578
- echo ""
579
- echo '```json'
580
- jq '{feature: .feature, metadata: .metadata}' "$RALPH_DIR/prd.json"
581
- echo '```'
582
- }
583
-
584
- # Helper: Inject scalability requirements
585
- _inject_scalability() {
586
- local has_scalability
587
- has_scalability=$(jq -r '.scalability // empty' "$RALPH_DIR/prd.json" 2>/dev/null)
588
- [[ -z "$has_scalability" ]] && return
589
-
590
- echo ""
591
- echo "## Scalability Requirements"
592
- echo ""
593
- echo "**IMPORTANT:** Follow these scalability rules."
594
- echo ""
595
- echo '```json'
596
- jq '.scalability' "$RALPH_DIR/prd.json"
597
- echo '```'
598
- echo ""
599
- echo "### Key Rules:"
600
- echo "- Always paginate list endpoints (never return unbounded arrays)"
601
- echo "- Avoid N+1 queries - eager load relationships"
602
- echo "- Add database indexes for frequently queried fields"
603
- echo "- Implement caching strategy as specified"
604
- echo "- Add rate limiting to public endpoints"
605
- }
606
-
607
- # Helper: Inject architecture guidelines
608
- _inject_architecture() {
609
- local has_architecture
610
- has_architecture=$(jq -r '.architecture // empty' "$RALPH_DIR/prd.json" 2>/dev/null)
611
- [[ -z "$has_architecture" ]] && return
612
-
613
- echo ""
614
- echo "## Architecture Guidelines"
615
- echo ""
616
- echo "**IMPORTANT:** Follow these architecture rules strictly."
617
- echo ""
618
- echo '```json'
619
- jq '.architecture' "$RALPH_DIR/prd.json"
620
- echo '```'
621
- echo ""
622
- echo "### Key Rules:"
623
- echo "- Put files in the specified directories"
624
- echo "- Reuse existing components listed in 'patterns.reuse'"
625
- echo "- Do NOT create anything in 'doNotCreate'"
626
- echo "- Keep files under $(jq -r '.architecture.principles.maxFileLines // 300' "$RALPH_DIR/prd.json") lines"
627
- echo "- Scripts go in scripts/, docs go in docs/"
628
- }
629
-
630
507
  # Helper: Build delta prompt for continuing session
631
- # Minimal context - just new story + any failure info
508
+ # Minimal context - just story ID + any failure info
632
509
  _build_delta_prompt() {
633
510
  local story="$1"
634
- local story_json="$2"
635
- local failure_context="${3:-}"
511
+ local failure_context="${2:-}"
636
512
 
637
513
  echo ""
638
514
  echo "---"
@@ -642,8 +518,10 @@ _build_delta_prompt() {
642
518
  if [[ -n "$failure_context" ]]; then
643
519
  echo "## Retry: Fix the errors below"
644
520
  echo ""
521
+ echo "Read \`.ralph/last_failure.txt\` for full error details."
522
+ echo ""
645
523
  echo '```'
646
- echo "$failure_context"
524
+ echo "$failure_context" | head -50
647
525
  echo '```'
648
526
  echo ""
649
527
  else
@@ -651,100 +529,79 @@ _build_delta_prompt() {
651
529
  local completed_count
652
530
  completed_count=$(jq '[.stories[] | select(.passes==true)] | length' "$RALPH_DIR/prd.json" 2>/dev/null || echo "0")
653
531
  if [[ "$completed_count" -gt 0 ]]; then
654
- echo "## Previous stories complete. Moving to next story."
532
+ echo "## Previous story complete. Moving to next."
655
533
  echo ""
656
- # Suggest compact if we've done several stories
657
- if [[ "$completed_count" -ge 3 ]]; then
658
- echo "*Consider running /compact if context feels heavy.*"
659
- echo ""
660
- fi
661
534
  fi
662
535
  fi
663
536
 
664
- echo "## Current Story"
665
- echo ""
666
- echo '```json'
667
- echo "$story_json"
668
- echo '```'
669
-
670
- # Include file guidance for the new story
671
- _inject_file_guidance "$story_json"
672
- _inject_story_scale "$story_json"
673
- _inject_styleguide "$story_json"
674
- }
675
-
676
- # Helper: Inject failure context from previous iteration
677
- _inject_failure_context() {
678
- local failure_context="$1"
679
- [[ -z "$failure_context" ]] && return
680
-
537
+ echo "## Current Story: $story"
681
538
  echo ""
682
- echo "## Previous Iteration Failed"
683
- echo ""
684
- echo "Fix the errors below. If a PRD test step is broken, you can fix it in .ralph/prd.json."
685
- echo ""
686
- echo '```'
687
- echo "$failure_context"
688
- echo '```'
539
+ echo "Read full story details from \`.ralph/prd.json\`"
689
540
  }
690
541
 
691
- # Helper: Inject signs (learned patterns)
542
+ # Helper: Inject signs (learned patterns) - ALWAYS inject these
692
543
  _inject_signs() {
693
- echo ""
694
- echo "## Signs (Learned Patterns)"
695
- echo ""
696
- echo "Apply these lessons from previous sessions:"
697
- echo ""
698
- if [[ -f "$RALPH_DIR/signs.json" ]]; then
699
- jq -r '.signs[] | "- [\(.category)] \(.pattern)"' "$RALPH_DIR/signs.json" 2>/dev/null || echo "(none yet)"
700
- else
701
- echo "(none yet)"
702
- fi
703
- }
544
+ [[ ! -f "$RALPH_DIR/signs.json" ]] && return
704
545
 
705
- # Helper: Inject developer DNA
706
- _inject_developer_dna() {
707
- [[ ! -f "$HOME/.claude/DNA.md" ]] && return
546
+ local sign_count
547
+ sign_count=$(jq '.signs | length' "$RALPH_DIR/signs.json" 2>/dev/null || echo "0")
548
+ [[ "$sign_count" == "0" ]] && return
708
549
 
709
550
  echo ""
710
- echo "## Developer DNA"
551
+ echo "## Signs (Learned Patterns) - FOLLOW THESE"
711
552
  echo ""
712
- echo "The developer has these working preferences:"
713
- echo ""
714
- cat "$HOME/.claude/DNA.md"
553
+ jq -r '.signs[] | "- [\(.category)] \(.pattern)"' "$RALPH_DIR/signs.json" 2>/dev/null
715
554
  }
716
555
 
717
- # Build the prompt with story context injected
556
+ # Build the prompt - LEAN version
557
+ # Claude reads context from prd.json, we just provide the story ID and signs
718
558
  # Usage: build_prompt <story_id> [failure_context] [is_continuation]
719
559
  build_prompt() {
720
560
  local story="$1"
721
561
  local failure_context="${2:-}"
722
562
  local is_continuation="${3:-false}"
723
563
 
724
- # Get story JSON once
725
- local story_json
726
- story_json=$(jq --arg id "$story" '.stories[] | select(.id==$id)' "$RALPH_DIR/prd.json")
727
-
728
564
  if [[ "$is_continuation" == "true" ]]; then
729
- # Delta prompt for continuing session - just new story context
730
- _build_delta_prompt "$story" "$story_json" "$failure_context"
565
+ # Delta prompt for continuing session
566
+ _build_delta_prompt "$story" "$failure_context"
731
567
  return
732
568
  fi
733
569
 
734
- # Full prompt for fresh session
570
+ # Full prompt for fresh session - LEAN
735
571
  cat "$PROMPT_FILE"
736
572
 
737
- # Inject all sections
738
- _inject_story_context "$story_json"
739
- _inject_file_guidance "$story_json"
740
- _inject_story_scale "$story_json"
741
- _inject_styleguide "$story_json"
742
- _inject_feature_context
743
- _inject_scalability
744
- _inject_architecture
745
- _inject_failure_context "$failure_context"
573
+ echo ""
574
+ echo "---"
575
+ echo ""
576
+ echo "## Current Story: $story"
577
+ echo ""
578
+ echo "Read full story details from \`.ralph/prd.json\` - it contains everything you need:"
579
+ echo "- \`story.files\` - which files to create/modify"
580
+ echo "- \`story.acceptanceCriteria\` - what must be true"
581
+ echo "- \`story.testSteps\` - verification commands"
582
+ echo "- \`story.contextFiles\` - idea files, styleguides to read"
583
+ echo "- \`story.mcp\` - browser tools for verification"
584
+ echo "- \`story.skills\` - relevant skills to reference"
585
+ echo ""
586
+ echo "Also read:"
587
+ echo "- \`prd.techStack\` - technologies in use"
588
+ echo "- \`prd.globalConstraints\` - rules for all stories"
589
+ echo "- \`.ralph/config.json\` - URLs and directories"
590
+
591
+ # Failure context if retrying
592
+ if [[ -n "$failure_context" ]]; then
593
+ echo ""
594
+ echo "## Previous Iteration Failed"
595
+ echo ""
596
+ echo "Read \`.ralph/last_failure.txt\` for details. Key error:"
597
+ echo ""
598
+ echo '```'
599
+ echo "$failure_context" | head -30
600
+ echo '```'
601
+ fi
602
+
603
+ # Signs are critical - always inject to prevent repeated mistakes
746
604
  _inject_signs
747
- _inject_developer_dna
748
605
  }
749
606
 
750
607
  # Print story completion summary
package/ralph/prd.sh CHANGED
@@ -96,6 +96,7 @@ ralph_prd() {
96
96
  printf '%s\n' ' "branch": "feature/feature-name",' >> "$prompt_file"
97
97
  printf '%s\n' ' "status": "pending"' >> "$prompt_file"
98
98
  printf '%s\n' ' },' >> "$prompt_file"
99
+ printf '%s\n' ' "originalContext": "PASTE THE FULL ORIGINAL NOTES/DESCRIPTION HERE - this preserves intent for Claude during implementation",' >> "$prompt_file"
99
100
  printf '%s\n' ' "metadata": {' >> "$prompt_file"
100
101
  printf '%s\n' ' "security": ["list of security requirements"],' >> "$prompt_file"
101
102
  printf '%s\n' ' "scaling": ["list of scaling concerns"],' >> "$prompt_file"
@@ -185,6 +186,10 @@ ralph_prd() {
185
186
  printf '%s\n' '- If complexity is "high" AND > 5 stories, MUST split' >> "$prompt_file"
186
187
  printf '%s\n' "- Each story should be completable in one Claude session (~10 min)" >> "$prompt_file"
187
188
  printf '\n%s\n' "If splitting is needed, generate ONLY phase 1 and note deferred items." >> "$prompt_file"
189
+ printf '\n%s\n' "## Original Context - IMPORTANT" >> "$prompt_file"
190
+ printf '\n%s\n' "Copy the FULL original feature notes into the 'originalContext' field verbatim." >> "$prompt_file"
191
+ printf '%s\n' "This preserves the user's original intent for Claude during implementation." >> "$prompt_file"
192
+ printf '%s\n' "Do NOT summarize - include the complete text." >> "$prompt_file"
188
193
  printf '\n%s\n' "## Output" >> "$prompt_file"
189
194
  printf '\n%s\n' "After questions are answered, output the prd.json content between these exact markers:" >> "$prompt_file"
190
195
  printf '%s\n' "--- BEGIN PRD.JSON ---" >> "$prompt_file"