flight-rules 0.13.8 → 0.13.9

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.
@@ -5,6 +5,27 @@ export interface RalphOptions {
5
5
  area?: string;
6
6
  branch?: string | boolean;
7
7
  }
8
+ export interface TaskGroupPlan {
9
+ id: string;
10
+ title: string;
11
+ filePath: string;
12
+ area: string;
13
+ incompleteTasks: Array<{
14
+ id: string;
15
+ title: string;
16
+ status: string;
17
+ }>;
18
+ }
19
+ /**
20
+ * Parse the discovery response from Claude into TaskGroupPlan objects.
21
+ * Returns null if the response cannot be parsed (tags not found).
22
+ * Returns empty array if ALL_COMPLETE.
23
+ */
24
+ export declare function parseDiscoveryResponse(output: string): TaskGroupPlan[] | null;
25
+ /**
26
+ * Build an execution prompt from the template and a task group plan.
27
+ */
28
+ export declare function buildExecutionPrompt(template: string, taskGroup: TaskGroupPlan): string;
8
29
  /**
9
30
  * Run the Ralph Loop - an autonomous agent loop that works through task groups
10
31
  */
@@ -4,7 +4,6 @@ import { spawn } from 'child_process';
4
4
  import { existsSync, readFileSync } from 'fs';
5
5
  import { join } from 'path';
6
6
  import { isFlightRulesInstalled, getFlightRulesDir } from '../utils/files.js';
7
- const COMPLETION_SIGNAL = '<ralph-signal>COMPLETE</ralph-signal>';
8
7
  /**
9
8
  * Generate a default branch name for Ralph work
10
9
  */
@@ -65,7 +64,7 @@ async function createAndCheckoutBranch(branchName) {
65
64
  return { success: true };
66
65
  }
67
66
  /**
68
- * Build area constraint text to append to prompt
67
+ * Build area constraint text to append to discovery prompt
69
68
  */
70
69
  function buildAreaConstraint(area) {
71
70
  return `
@@ -78,7 +77,7 @@ function buildAreaConstraint(area) {
78
77
 
79
78
  - Only scan \`docs/implementation/${area}*/\` for task groups
80
79
  - Ignore all other areas
81
- - If no incomplete task groups exist in Area ${area}, output the completion signal
80
+ - If no incomplete task groups exist in Area ${area}, respond with ALL_COMPLETE
82
81
  `;
83
82
  }
84
83
  /**
@@ -177,23 +176,93 @@ async function runClaudeWithPrompt(promptContent, verbose) {
177
176
  function sleep(ms) {
178
177
  return new Promise((resolve) => setTimeout(resolve, ms));
179
178
  }
179
+ /**
180
+ * Parse the discovery response from Claude into TaskGroupPlan objects.
181
+ * Returns null if the response cannot be parsed (tags not found).
182
+ * Returns empty array if ALL_COMPLETE.
183
+ */
184
+ export function parseDiscoveryResponse(output) {
185
+ // Extract content between <ralph-discovery> tags
186
+ const match = output.match(/<ralph-discovery>([\s\S]*?)<\/ralph-discovery>/);
187
+ if (!match) {
188
+ return null;
189
+ }
190
+ const content = match[1].trim();
191
+ // Handle ALL_COMPLETE case
192
+ if (content === 'ALL_COMPLETE') {
193
+ return [];
194
+ }
195
+ const taskGroups = [];
196
+ let currentGroup = null;
197
+ for (const line of content.split('\n')) {
198
+ const trimmed = line.trim();
199
+ if (!trimmed)
200
+ continue;
201
+ if (trimmed.startsWith('TASK_GROUP|')) {
202
+ const parts = trimmed.split('|');
203
+ if (parts.length >= 5) {
204
+ currentGroup = {
205
+ id: parts[1],
206
+ title: parts[2],
207
+ filePath: parts[3],
208
+ area: parts[4],
209
+ incompleteTasks: [],
210
+ };
211
+ taskGroups.push(currentGroup);
212
+ }
213
+ }
214
+ else if (trimmed.startsWith('TASK|') && currentGroup) {
215
+ const parts = trimmed.split('|');
216
+ if (parts.length >= 4) {
217
+ currentGroup.incompleteTasks.push({
218
+ id: parts[1],
219
+ title: parts[2],
220
+ status: parts[3],
221
+ });
222
+ }
223
+ }
224
+ // Skip malformed lines silently
225
+ }
226
+ return taskGroups;
227
+ }
228
+ /**
229
+ * Build an execution prompt from the template and a task group plan.
230
+ */
231
+ export function buildExecutionPrompt(template, taskGroup) {
232
+ // Render incomplete tasks as markdown bullet points
233
+ const tasksList = taskGroup.incompleteTasks
234
+ .map((t) => `- **${t.id}**: ${t.title} (${t.status})`)
235
+ .join('\n');
236
+ return template
237
+ .replace(/\{\{TASK_GROUP_ID\}\}/g, taskGroup.id)
238
+ .replace(/\{\{TASK_GROUP_TITLE\}\}/g, taskGroup.title)
239
+ .replace(/\{\{TASK_GROUP_FILE_PATH\}\}/g, taskGroup.filePath)
240
+ .replace(/\{\{INCOMPLETE_TASKS_LIST\}\}/g, tasksList);
241
+ }
180
242
  /**
181
243
  * Run the Ralph Loop - an autonomous agent loop that works through task groups
182
244
  */
183
245
  export async function ralph(options) {
184
246
  const cwd = process.cwd();
185
247
  const flightRulesDir = getFlightRulesDir(cwd);
186
- const promptPath = join(flightRulesDir, 'prompts', 'ralph-loop.md');
248
+ const discoveryPromptPath = join(flightRulesDir, 'prompts', 'ralph-discovery.md');
249
+ const executionPromptPath = join(flightRulesDir, 'prompts', 'ralph-execution.md');
187
250
  // Verify Flight Rules is installed
188
251
  if (!isFlightRulesInstalled(cwd)) {
189
252
  p.log.error('Flight Rules is not installed in this directory.');
190
253
  p.log.info('Run `flight-rules init` first.');
191
254
  return;
192
255
  }
193
- // Verify prompt file exists
194
- if (!existsSync(promptPath)) {
195
- p.log.error('Ralph prompt file not found.');
196
- p.log.info(`Expected at: ${promptPath}`);
256
+ // Verify both prompt files exist
257
+ if (!existsSync(discoveryPromptPath)) {
258
+ p.log.error('Ralph discovery prompt file not found.');
259
+ p.log.info(`Expected at: ${discoveryPromptPath}`);
260
+ p.log.info('You may need to run `flight-rules upgrade` to get the latest files.');
261
+ return;
262
+ }
263
+ if (!existsSync(executionPromptPath)) {
264
+ p.log.error('Ralph execution prompt file not found.');
265
+ p.log.info(`Expected at: ${executionPromptPath}`);
197
266
  p.log.info('You may need to run `flight-rules upgrade` to get the latest files.');
198
267
  return;
199
268
  }
@@ -204,10 +273,12 @@ export async function ralph(options) {
204
273
  p.log.info('Install it with: npm install -g @anthropic-ai/claude-code');
205
274
  return;
206
275
  }
207
- // Read the prompt content and optionally append area constraint
208
- let promptContent = readFileSync(promptPath, 'utf-8');
276
+ // Read prompt files
277
+ let discoveryPrompt = readFileSync(discoveryPromptPath, 'utf-8');
278
+ const executionTemplate = readFileSync(executionPromptPath, 'utf-8');
279
+ // Optionally append area constraint to discovery prompt
209
280
  if (options.area) {
210
- promptContent += buildAreaConstraint(options.area);
281
+ discoveryPrompt += buildAreaConstraint(options.area);
211
282
  }
212
283
  // Determine branch name if branching is requested
213
284
  let branchName;
@@ -217,15 +288,17 @@ export async function ralph(options) {
217
288
  // Dry run mode
218
289
  if (options.dryRun) {
219
290
  p.log.info(pc.yellow('Dry run mode - showing what would be executed:'));
220
- p.log.message(` Prompt file: ${promptPath}`);
221
- p.log.message(` Max iterations: ${options.maxIterations}`);
291
+ p.log.message(` Discovery prompt: ${discoveryPromptPath}`);
292
+ p.log.message(` Execution prompt: ${executionPromptPath}`);
293
+ p.log.message(` Max task groups: ${options.maxIterations}`);
222
294
  if (options.area) {
223
295
  p.log.message(` Area constraint: ${options.area}`);
224
296
  }
225
297
  if (branchName) {
226
298
  p.log.message(` Branch: ${branchName}`);
227
299
  }
228
- p.log.message(` Command: claude --dangerously-skip-permissions -p < "${promptPath}"`);
300
+ p.log.message(' Phase 1: Discovery identify incomplete task groups');
301
+ p.log.message(' Phase 2: Execution — one Claude instance per task group');
229
302
  return;
230
303
  }
231
304
  // Handle branch creation if requested
@@ -249,7 +322,7 @@ export async function ralph(options) {
249
322
  // Start the loop
250
323
  console.log();
251
324
  p.intro(pc.bgMagenta(pc.white(' Flight Rules Ralph Loop ')));
252
- p.log.info(`Starting autonomous loop with max ${options.maxIterations} iterations`);
325
+ p.log.info(`Two-phase mode: discover then execute (max ${options.maxIterations} task groups)`);
253
326
  if (options.area) {
254
327
  p.log.info(`Targeting Area: ${pc.cyan(options.area)}`);
255
328
  }
@@ -258,40 +331,97 @@ export async function ralph(options) {
258
331
  }
259
332
  p.log.warn('Press Ctrl+C to stop the loop at any time');
260
333
  console.log();
261
- for (let i = 1; i <= options.maxIterations; i++) {
334
+ // ── Phase 1: Discovery ──────────────────────────────────────────────
335
+ p.log.step(pc.magenta('Phase 1: Discovery'));
336
+ p.log.info('Scanning implementation docs for incomplete task groups...');
337
+ console.log();
338
+ let taskGroups;
339
+ try {
340
+ const discoveryResult = await runClaudeWithPrompt(discoveryPrompt, options.verbose);
341
+ if (discoveryResult.exitCode !== 0) {
342
+ p.log.warn(`Discovery phase exited with code ${discoveryResult.exitCode}`);
343
+ }
344
+ const parsed = parseDiscoveryResponse(discoveryResult.output);
345
+ if (parsed === null) {
346
+ p.log.error('Could not parse discovery response. Expected <ralph-discovery> tags.');
347
+ p.log.info('Run with --verbose to see the full Claude output.');
348
+ p.outro(pc.red('Ralph loop aborted'));
349
+ return;
350
+ }
351
+ taskGroups = parsed;
352
+ }
353
+ catch (error) {
354
+ p.log.error(`Discovery phase failed: ${error instanceof Error ? error.message : String(error)}`);
355
+ p.outro(pc.red('Ralph loop aborted'));
356
+ return;
357
+ }
358
+ // Handle ALL_COMPLETE
359
+ if (taskGroups.length === 0) {
360
+ console.log();
361
+ p.log.success(pc.green('All task groups complete!'));
362
+ p.outro(pc.green('Ralph loop finished — nothing to do'));
363
+ return;
364
+ }
365
+ // Display discovered task groups
366
+ console.log();
367
+ p.log.info(`Found ${taskGroups.length} incomplete task group(s):`);
368
+ for (const tg of taskGroups) {
369
+ p.log.message(` ${pc.cyan(tg.id)} — ${tg.title} (${tg.incompleteTasks.length} tasks)`);
370
+ }
371
+ console.log();
372
+ // Limit to max iterations
373
+ const groupsToExecute = taskGroups.slice(0, options.maxIterations);
374
+ if (taskGroups.length > options.maxIterations) {
375
+ p.log.info(`Will execute ${options.maxIterations} of ${taskGroups.length} task groups (--max-iterations)`);
376
+ console.log();
377
+ }
378
+ // ── Phase 2: Execution ──────────────────────────────────────────────
379
+ p.log.step(pc.magenta('Phase 2: Execution'));
380
+ console.log();
381
+ let completed = 0;
382
+ let failed = 0;
383
+ for (let i = 0; i < groupsToExecute.length; i++) {
384
+ const taskGroup = groupsToExecute[i];
262
385
  const separator = '='.repeat(50);
263
386
  p.log.step(pc.dim(separator));
264
- p.log.step(pc.magenta(` Ralph Iteration ${i} of ${options.maxIterations}`));
387
+ p.log.step(pc.magenta(` Task Group ${i + 1} of ${groupsToExecute.length}: ${taskGroup.id} — ${taskGroup.title}`));
265
388
  p.log.step(pc.dim(separator));
266
389
  console.log();
267
390
  try {
268
- const result = await runClaudeWithPrompt(promptContent, options.verbose);
269
- // Check for completion signal
270
- if (result.output.includes(COMPLETION_SIGNAL)) {
271
- console.log();
272
- p.log.success(pc.green('All task groups complete!'));
273
- p.log.info(`Finished at iteration ${i} of ${options.maxIterations}`);
274
- p.outro(pc.green('Ralph loop finished successfully'));
275
- return;
276
- }
391
+ const executionPrompt = buildExecutionPrompt(executionTemplate, taskGroup);
392
+ const result = await runClaudeWithPrompt(executionPrompt, options.verbose);
277
393
  if (result.exitCode !== 0) {
278
- p.log.warn(`Claude exited with code ${result.exitCode}`);
394
+ p.log.warn(`Task group ${taskGroup.id} exited with code ${result.exitCode}`);
395
+ failed++;
279
396
  }
280
- p.log.info(`Iteration ${i} complete. Continuing...`);
281
- // Small delay between iterations to allow for any cleanup
282
- if (i < options.maxIterations) {
283
- await sleep(2000);
397
+ else {
398
+ p.log.success(`Task group ${taskGroup.id} complete`);
399
+ completed++;
284
400
  }
285
401
  }
286
402
  catch (error) {
287
- p.log.error(`Error in iteration ${i}: ${error instanceof Error ? error.message : String(error)}`);
288
- // Continue to next iteration despite errors
403
+ p.log.error(`Error executing task group ${taskGroup.id}: ${error instanceof Error ? error.message : String(error)}`);
404
+ failed++;
405
+ // Continue to next task group despite errors
406
+ }
407
+ // Small delay between executions
408
+ if (i < groupsToExecute.length - 1) {
409
+ await sleep(2000);
289
410
  }
290
411
  }
291
- // Reached max iterations
412
+ // Summary
292
413
  console.log();
293
- p.log.warn(`Reached max iterations (${options.maxIterations}) without completing all tasks.`);
294
- p.log.info('Check docs/progress.md and docs/ralph_logs/ for current status.');
295
- p.log.info('Run `flight-rules ralph` again to continue.');
296
- p.outro(pc.yellow('Ralph loop stopped'));
414
+ const separator = '='.repeat(50);
415
+ p.log.step(pc.dim(separator));
416
+ p.log.info(`Summary: ${completed} completed, ${failed} failed out of ${groupsToExecute.length} task groups`);
417
+ if (taskGroups.length > options.maxIterations) {
418
+ p.log.info(`${taskGroups.length - options.maxIterations} task group(s) remaining. Run \`flight-rules ralph\` again to continue.`);
419
+ }
420
+ if (failed > 0) {
421
+ p.log.info('Check docs/ralph_logs/ for details on failures.');
422
+ p.outro(pc.yellow('Ralph loop finished with errors'));
423
+ }
424
+ else {
425
+ p.outro(pc.green('Ralph loop finished successfully'));
426
+ }
297
427
  }
package/dist/index.js CHANGED
@@ -159,7 +159,7 @@ ${pc.bold('Adapter Options:')}
159
159
  --all Generate all adapters
160
160
 
161
161
  ${pc.bold('Ralph Options:')}
162
- --max-iterations, -n <n> Maximum iterations before stopping (default: 10)
162
+ --max-iterations, -n <n> Maximum task groups to execute (default: 10)
163
163
  --area <id> Focus on a specific implementation area (e.g., 2 or 2-cli-core)
164
164
  --branch [name] Create a new branch before starting (auto-generates if no name)
165
165
  --dry-run Show what would be executed without running
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "flight-rules",
3
- "version": "0.13.8",
3
+ "version": "0.13.9",
4
4
  "description": "An opinionated framework for AI-assisted software development",
5
5
  "type": "module",
6
6
  "main": "dist/index.js",
package/payload/AGENTS.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # Flight Rules – Agent Guidelines
2
2
 
3
- flight_rules_version: 0.13.8
3
+ flight_rules_version: 0.13.9
4
4
 
5
5
  This file defines how agents (Claude Code, Cursor, etc.) should work on software projects using the Flight Rules system.
6
6
 
@@ -0,0 +1,50 @@
1
+ # Flight Rules Discovery Agent
2
+
3
+ You are a discovery agent for Flight Rules. Your ONLY job is to scan implementation docs and report which task groups have incomplete tasks. Do NOT implement anything.
4
+
5
+ ## Instructions
6
+
7
+ 1. Read `docs/implementation/overview.md` to understand the area/task-group structure
8
+ 2. Scan each Area directory in `docs/implementation/`
9
+ 3. For each Task Group file (.md), check every task's status
10
+ 4. Report all task groups that contain any task with status other than ✅ Complete (i.e., 🔵 Planned, 🟡 In Progress, or ⏸️ Blocked)
11
+
12
+ ## Response Format
13
+
14
+ Respond with a pipe-delimited report inside `<ralph-discovery>` tags. Use EXACTLY this format:
15
+
16
+ ```
17
+ <ralph-discovery>
18
+ TASK_GROUP|{id}|{title}|{filePath}|{areaDir}
19
+ TASK|{taskId}|{taskTitle}|{status}
20
+ TASK|{taskId}|{taskTitle}|{status}
21
+ TASK_GROUP|{id}|{title}|{filePath}|{areaDir}
22
+ TASK|{taskId}|{taskTitle}|{status}
23
+ </ralph-discovery>
24
+ ```
25
+
26
+ - Each `TASK_GROUP` line is followed by its `TASK` lines (only incomplete tasks)
27
+ - `{id}` = task group ID as written in the file (e.g., "1.1", "2.3")
28
+ - `{title}` = task group title
29
+ - `{filePath}` = relative path from project root to the task group file
30
+ - `{areaDir}` = area directory name (e.g., "1-project-setup", "2-cli-core")
31
+ - `{taskId}` = individual task ID (e.g., "1.1.1", "2.3.2")
32
+ - `{taskTitle}` = individual task title
33
+ - `{status}` = one of: planned, in_progress, blocked
34
+
35
+ If ALL tasks in ALL task groups are ✅ Complete, respond with:
36
+
37
+ ```
38
+ <ralph-discovery>
39
+ ALL_COMPLETE
40
+ </ralph-discovery>
41
+ ```
42
+
43
+ ## Rules
44
+
45
+ - Do NOT implement or modify any code
46
+ - Do NOT create or modify any files
47
+ - Do NOT run any scripts or quality checks
48
+ - ONLY read implementation files and report status
49
+ - Always include the `<ralph-discovery>` tags in your response
50
+ - List task groups in the order they should be worked on (by area number, then task group number)
@@ -0,0 +1,100 @@
1
+ # Flight Rules Autonomous Agent — Scoped Execution
2
+
3
+ You are an autonomous coding agent implementing a SPECIFIC Flight Rules task group. Work ONLY on the task group described below.
4
+
5
+ ## Your Assignment
6
+
7
+ **Task Group:** {{TASK_GROUP_ID}} — {{TASK_GROUP_TITLE}}
8
+ **Task Group File:** {{TASK_GROUP_FILE_PATH}}
9
+
10
+ ### Incomplete Tasks
11
+
12
+ {{INCOMPLETE_TASKS_LIST}}
13
+
14
+ ## Instructions
15
+
16
+ 1. **Preparation**
17
+ - Read `.flight-rules/AGENTS.md` for framework guidelines
18
+ - Read `docs/prd.md` for project requirements
19
+ - Read `docs/progress.md` for recent work history (especially the last entry)
20
+ - Read `docs/critical-learnings.md` for patterns and gotchas
21
+ - Read `package.json` to discover available scripts
22
+ - Read the task group file: `{{TASK_GROUP_FILE_PATH}}`
23
+
24
+ 2. **For EACH incomplete task listed above:**
25
+ - Update task status to 🟡 In Progress in the task group file
26
+ - Implement according to the Approach section in the task group file
27
+ - Run quality checks (see below)
28
+ - Verify against Acceptance Criteria
29
+ - Update task status to ✅ Complete
30
+
31
+ 3. **After All Tasks Complete**
32
+ - Verify the entire Task Group is complete
33
+ - Create a Ralph log entry (see Logging section)
34
+ - If you discovered reusable patterns or gotchas, append to `docs/critical-learnings.md`
35
+ - Commit all changes:
36
+ ```bash
37
+ git add -A
38
+ git commit -m "feat: {{TASK_GROUP_ID}} - {{TASK_GROUP_TITLE}}"
39
+ ```
40
+
41
+ 4. **Quality Checks (Run Before Every Commit)**
42
+ Read `package.json` to discover available scripts. Then run the relevant ones:
43
+ - If `typecheck` or `tsc` script exists: run it
44
+ - If `test` script exists: run it
45
+ - If `lint` script exists: run it
46
+ - If `build` script exists: run it to verify compilation
47
+
48
+ All checks must pass before committing. If a check fails, fix the issue and retry.
49
+
50
+ If you attempt to fix the same issue 3 times without success, document the blocker in your Ralph log and mark the task as ⏸️ Blocked. Then move to the next task.
51
+
52
+ ## Logging
53
+
54
+ After completing the task group (or when blocked), create or append to `docs/ralph_logs/YYYYMMDD_HHMM_ralph.md`:
55
+
56
+ ```markdown
57
+ # Ralph Log: YYYY-MM-DD HH:MM
58
+
59
+ ## Task Group: {{TASK_GROUP_ID}} - {{TASK_GROUP_TITLE}}
60
+
61
+ ### Tasks Completed
62
+ - [Task ID]: [Brief description of what was done]
63
+
64
+ ### Files Changed
65
+ - `path/to/file.ts` - [what changed]
66
+
67
+ ### Quality Check Results
68
+ - typecheck: pass/fail (details)
69
+ - test: pass/fail (details)
70
+ - lint: pass/fail (details)
71
+
72
+ ### Blockers (if any)
73
+ - [Description of blocker and attempts made]
74
+
75
+ ### Learnings
76
+ - [Patterns discovered, gotchas encountered]
77
+ ```
78
+
79
+ Also update `docs/progress.md` with a brief entry:
80
+ ```markdown
81
+ ### YYYY-MM-DD HH:MM - {{TASK_GROUP_ID}} (Ralph)
82
+ - Summary of work done
83
+ - See: ralph_logs/YYYYMMDD_HHMM_ralph.md
84
+ ```
85
+
86
+ ## Rules
87
+
88
+ - Work ONLY on the tasks listed above — do NOT look for other task groups
89
+ - NEVER ask for human input — work autonomously
90
+ - NEVER skip quality checks
91
+ - If blocked after 3 attempts on the same issue, document it and move on
92
+ - Commit after completing all tasks in this group, not after each individual task
93
+ - Keep commits atomic and CI-friendly
94
+
95
+ ## Status Legend
96
+
97
+ - 🔵 Planned — Not started
98
+ - 🟡 In Progress — Currently being worked on
99
+ - ✅ Complete — Done and verified
100
+ - ⏸️ Blocked — Cannot proceed (document why in Ralph log)
@@ -1,113 +0,0 @@
1
- # Flight Rules Autonomous Agent
2
-
3
- You are an autonomous coding agent implementing Flight Rules task groups.
4
-
5
- ## Your Mission
6
-
7
- 1. **Find Next Task Group**
8
- - Read `docs/implementation/overview.md`
9
- - Scan all Area directories in `docs/implementation/`
10
- - Find the first Task Group file (.md) with any task having status 🔵 Planned or 🟡 In Progress
11
- - If ALL tasks across ALL task groups are ✅ Complete, proceed to step 2
12
- - Otherwise, proceed to step 3
13
-
14
- 2. **If ALL Tasks in ALL Task Groups Are Complete**
15
- - ONLY output the completion signal when you have verified that EVERY task in EVERY task group is ✅ Complete
16
- - Output exactly: `<ralph-signal>COMPLETE</ralph-signal>`
17
- - Stop immediately - do not output anything else after this
18
- - **IMPORTANT**: Do NOT output this signal just because the current task group is done. The loop will automatically continue to the next iteration.
19
-
20
- 3. **If Task Group Found**
21
- - Read the Task Group file completely
22
- - For EACH task in the group that is not ✅ Complete:
23
- - Update task status to 🟡 In Progress
24
- - Implement according to the Approach section
25
- - Run quality checks (see below)
26
- - Verify against Acceptance Criteria
27
- - Update task status to ✅ Complete
28
-
29
- 4. **After All Tasks in Group Complete**
30
- - Verify the entire Task Group is complete
31
- - Create a Ralph log entry (see Logging section below)
32
- - If you discovered reusable patterns or gotchas, append to `docs/critical-learnings.md`
33
- - Commit all changes:
34
- ```bash
35
- git add -A
36
- git commit -m "feat: [Task Group ID] - [Task Group Title]"
37
- ```
38
- - **STOP HERE** - Do NOT output the completion signal. The loop will automatically start the next iteration to find more task groups.
39
-
40
- 5. **Quality Checks (Run Before Every Commit)**
41
- First, read `package.json` to discover available scripts. Then run the relevant ones:
42
- - If `typecheck` or `tsc` script exists: run it
43
- - If `test` script exists: run it
44
- - If `lint` script exists: run it
45
- - If `build` script exists: run it to verify compilation
46
-
47
- All checks must pass before committing. If a check fails, fix the issue and retry.
48
-
49
- If you attempt to fix the same issue 3 times within this session without success, document the blocker in your Ralph log and mark the task as ⏸️ Blocked. Then move to the next task.
50
-
51
- ## Logging
52
-
53
- Create verbose logs for each Ralph session. After completing a task group (or when blocked):
54
-
55
- 1. Create or append to `docs/ralph_logs/YYYYMMDD_HHMM_ralph.md`:
56
-
57
- ```markdown
58
- # Ralph Log: YYYY-MM-DD HH:MM
59
-
60
- ## Task Group: [ID] - [Title]
61
-
62
- ### Tasks Completed
63
- - [Task ID]: [Brief description of what was done]
64
-
65
- ### Files Changed
66
- - `path/to/file.ts` - [what changed]
67
-
68
- ### Quality Check Results
69
- - typecheck: ✅ passed / ❌ failed (details)
70
- - test: ✅ passed / ❌ failed (details)
71
- - lint: ✅ passed / ❌ failed (details)
72
-
73
- ### Blockers (if any)
74
- - [Description of blocker and attempts made]
75
-
76
- ### Learnings
77
- - [Patterns discovered, gotchas encountered]
78
- ```
79
-
80
- 2. Also update `docs/progress.md` with a brief entry:
81
- ```markdown
82
- ### YYYY-MM-DD HH:MM - [Task Group ID] (Ralph)
83
- - Summary of work done
84
- - See: ralph_logs/YYYYMMDD_HHMM_ralph.md
85
- ```
86
-
87
- ## Rules
88
-
89
- - Work on ONE task group per iteration
90
- - NEVER output the COMPLETE signal unless ALL tasks in ALL task groups are ✅ Complete
91
- - NEVER ask for human input - work autonomously
92
- - NEVER skip quality checks
93
- - If blocked after 3 attempts on the same issue, document it and move on
94
- - Commit after completing each task group, not after each individual task
95
- - Keep commits atomic and CI-friendly
96
- - After committing a task group, just STOP - the loop will automatically continue
97
-
98
- ## Status Legend
99
-
100
- - 🔵 Planned - Not started
101
- - 🟡 In Progress - Currently being worked on
102
- - ✅ Complete - Done and verified
103
- - ⏸️ Blocked - Cannot proceed (document why in Ralph log)
104
-
105
- ## Files to Read on Startup
106
-
107
- Before starting work, read these files to understand context:
108
- - `.flight-rules/AGENTS.md` - Framework guidelines
109
- - `docs/prd.md` - Project requirements
110
- - `docs/progress.md` - Recent work history (especially the last entry)
111
- - `docs/critical-learnings.md` - Patterns and gotchas to follow
112
- - `docs/implementation/overview.md` - Implementation structure
113
- - `package.json` - Available scripts for quality checks