ralph/constants.rs
1//! Centralized constants for the Ralph CLI.
2//!
3//! This module consolidates all magic numbers, limits, and default values
4//! to improve maintainability and prevent drift between duplicated values.
5//!
6//! Responsibilities:
7//! - Provide a single source of truth for compile-time constants.
8//! - Organize constants by domain (buffers, limits, timeouts, UI, etc.).
9//! - Prevent accidental drift between duplicated constant definitions.
10//!
11//! Not handled here:
12//! - Runtime configuration values (see `crate::config`).
13//! - User-customizable thresholds (see `crate::contracts::Config`).
14//!
15//! Invariants/assumptions:
16//! - All constants are `pub` within their submodule; visibility is controlled by module exports.
17//! - Constants that appear in multiple places must be defined here and imported elsewhere.
18
19/// Buffer size limits for output handling and memory management.
20pub mod buffers {
21 /// Maximum size for ANSI buffer (10MB).
22 /// Reduced from 100MB to prevent memory pressure during runner execution.
23 pub const MAX_ANSI_BUFFER_SIZE: usize = 10 * 1024 * 1024;
24
25 /// Maximum line length before truncation (10MB).
26 /// Reduced from 100MB to prevent memory pressure with runaway runner output.
27 pub const MAX_LINE_LENGTH: usize = 10 * 1024 * 1024;
28
29 /// Maximum buffer size for stream processing (10MB).
30 /// Reduced from 100MB to prevent memory pressure during long-running tasks.
31 pub const MAX_BUFFER_SIZE: usize = 10 * 1024 * 1024;
32
33 /// Maximum log lines to retain for interactive log viewers.
34 pub const MAX_LOG_LINES: usize = 10_000;
35
36 /// Maximum tool value length before truncation.
37 pub const TOOL_VALUE_MAX_LEN: usize = 160;
38
39 /// Maximum instruction file size (128KB).
40 pub const MAX_INSTRUCTION_BYTES: usize = 128 * 1024;
41
42 /// Maximum stdout capture size for timeouts (128KB).
43 pub const TIMEOUT_STDOUT_CAPTURE_MAX_BYTES: usize = 128 * 1024;
44
45 /// Maximum bounded capture size for managed subprocess stdout/stderr tails.
46 pub const MANAGED_SUBPROCESS_CAPTURE_MAX_BYTES: usize = 256 * 1024;
47
48 /// Maximum bounded capture size for CI gate stdout/stderr tails.
49 pub const MANAGED_SUBPROCESS_CI_CAPTURE_MAX_BYTES: usize = 4 * 1024 * 1024;
50
51 /// Number of output tail lines to display.
52 pub const OUTPUT_TAIL_LINES: usize = 20;
53
54 /// Maximum characters per output tail line.
55 pub const OUTPUT_TAIL_LINE_MAX_CHARS: usize = 200;
56}
57
58/// Operational limits and thresholds.
59pub mod limits {
60 /// Auto-retry limit for CI gate failures.
61 pub const CI_GATE_AUTO_RETRY_LIMIT: u8 = 10;
62
63 /// Maximum automatic recovery attempts after runner signal termination.
64 pub const MAX_SIGNAL_RESUMES: u8 = 5;
65
66 /// Number of consecutive CI failures with the same error pattern before escalation.
67 /// After this many identical failures, Ralph stops retrying and requires intervention.
68 pub const CI_FAILURE_ESCALATION_THRESHOLD: u8 = 3;
69
70 /// Maximum consecutive failures before aborting run loop.
71 pub const MAX_CONSECUTIVE_FAILURES: u32 = 50;
72
73 /// Maximum IDs to generate per invocation.
74 pub const MAX_COUNT: usize = 100;
75
76 /// Maximum lock cleanup retry attempts.
77 pub const MAX_RETRIES: u32 = 3;
78
79 /// Minimum environment variable value length for redaction.
80 pub const MIN_ENV_VALUE_LEN: usize = 6;
81
82 /// Default queue file size warning threshold (KB).
83 pub const DEFAULT_SIZE_WARNING_THRESHOLD_KB: u32 = 500;
84
85 /// Default task count warning threshold.
86 pub const DEFAULT_TASK_COUNT_WARNING_THRESHOLD: u32 = 500;
87
88 /// Maximum LFS pointer file size (bytes).
89 pub const MAX_POINTER_SIZE: u64 = 1024;
90
91 /// Maximum number of queue backup files to retain in `.ralph/cache`.
92 pub const MAX_QUEUE_BACKUP_FILES: usize = 50;
93
94 /// Maximum number of undo snapshots to retain in `.ralph/cache/undo`.
95 pub const MAX_UNDO_SNAPSHOTS: usize = 20;
96}
97
98/// Timeout and interval durations.
99pub mod timeouts {
100 use std::time::Duration;
101
102 /// Default session timeout in hours.
103 pub const DEFAULT_SESSION_TIMEOUT_HOURS: u64 = 24;
104
105 /// Spinner animation update interval in milliseconds.
106 pub const SPINNER_UPDATE_INTERVAL_MS: u64 = 80;
107
108 /// Temporary file retention period (7 days).
109 ///
110 /// Files older than this are cleaned up:
111 /// - On CLI startup (main.rs)
112 /// - When building runner commands (with_temp_prompt_file)
113 /// - When running `ralph cleanup` command
114 ///
115 /// Default: 7 days. This balances keeping safeguard dumps available for
116 /// debugging against preventing indefinite accumulation.
117 pub const TEMP_RETENTION: Duration = Duration::from_secs(60 * 60 * 24 * 7);
118
119 /// Lock cleanup retry delays in milliseconds.
120 pub const DELAYS_MS: [u64; 3] = [10, 50, 100];
121
122 /// Managed subprocess timeout for short probes (doctor, availability checks).
123 pub const MANAGED_SUBPROCESS_PROBE_TIMEOUT: Duration = Duration::from_secs(15);
124
125 /// Managed subprocess timeout for standard git operations.
126 pub const MANAGED_SUBPROCESS_GIT_TIMEOUT: Duration = Duration::from_secs(120);
127
128 /// Managed subprocess timeout for GitHub CLI operations.
129 pub const MANAGED_SUBPROCESS_GH_TIMEOUT: Duration = Duration::from_secs(180);
130
131 /// Managed subprocess timeout for processor plugin hooks.
132 pub const MANAGED_SUBPROCESS_PLUGIN_TIMEOUT: Duration = Duration::from_secs(300);
133
134 /// Managed subprocess timeout for CI gate execution.
135 pub const MANAGED_SUBPROCESS_CI_TIMEOUT: Duration = Duration::from_secs(60 * 30);
136
137 /// Grace period after SIGINT before escalating to SIGKILL for managed subprocesses.
138 pub const MANAGED_SUBPROCESS_INTERRUPT_GRACE: Duration = Duration::from_secs(2);
139
140 /// Polling cadence for managed subprocess wait loops.
141 pub const MANAGED_SUBPROCESS_POLL_INTERVAL: Duration = Duration::from_millis(50);
142
143 /// Best-effort reap timeout after a managed subprocess receives SIGKILL.
144 pub const MANAGED_SUBPROCESS_REAP_TIMEOUT: Duration = Duration::from_secs(5);
145
146 /// Polling cadence for cancellation-aware retry waits.
147 pub const MANAGED_RETRY_POLL_INTERVAL: Duration = Duration::from_millis(50);
148
149 /// How long terminal worker records are retained before stale pruning.
150 ///
151 /// This prevents immediate task reselection while avoiding permanent capacity blockers.
152 pub const PARALLEL_TERMINAL_WORKER_TTL: Duration =
153 Duration::from_secs(60 * 60 * DEFAULT_SESSION_TIMEOUT_HOURS);
154}
155
156/// UI layout and dimension constants.
157pub mod ui {
158 /// Threshold for narrow layout mode.
159 pub const NARROW_LAYOUT_WIDTH: u16 = 90;
160
161 /// Minimum width for board view.
162 pub const BOARD_MIN_WIDTH: u16 = 100;
163
164 /// Gutter width between columns.
165 pub const COLUMN_GUTTER: u16 = 1;
166
167 /// Number of task builder fields.
168 pub const TASK_BUILDER_FIELD_COUNT: usize = 7;
169}
170
171/// Queue configuration constants.
172pub mod queue {
173 /// Default queue ID prefix.
174 pub const DEFAULT_ID_PREFIX: &str = "RQ";
175
176 /// Default queue file path (relative to repo root).
177 pub const DEFAULT_QUEUE_FILE: &str = ".ralph/queue.jsonc";
178
179 /// Default done file path (relative to repo root).
180 pub const DEFAULT_DONE_FILE: &str = ".ralph/done.jsonc";
181
182 /// Default config file path (relative to repo root).
183 pub const DEFAULT_CONFIG_FILE: &str = ".ralph/config.jsonc";
184
185 /// Default maximum dependency depth.
186 pub const DEFAULT_MAX_DEPENDENCY_DEPTH: u8 = 10;
187
188 /// Aging threshold: warning days (low priority).
189 pub const AGING_WARNING_DAYS: u32 = 7;
190
191 /// Aging threshold: stale days (medium priority).
192 pub const AGING_STALE_DAYS: u32 = 14;
193
194 /// Aging threshold: rotten days (high priority).
195 pub const AGING_ROTTEN_DAYS: u32 = 30;
196}
197
198/// Git-related constants.
199pub mod git {
200 /// Default branch prefix for parallel execution.
201 pub const DEFAULT_BRANCH_PREFIX: &str = "ralph/";
202
203 /// Sample task ID for branch validation.
204 pub const SAMPLE_TASK_ID: &str = "RQ-0001";
205}
206
207/// Runner-related constants.
208pub mod runner {
209 /// Default CI gate command.
210 pub const DEFAULT_CI_GATE_COMMAND: &str = "make ci";
211
212 /// Supported phase values (1-3).
213 pub const MIN_PHASES: u8 = 1;
214 pub const MAX_PHASES: u8 = 3;
215
216 /// Minimum iterations value.
217 pub const MIN_ITERATIONS: u8 = 1;
218 pub const MIN_ITERATIONS_U32: u32 = 1;
219
220 /// Minimum workers for parallel execution.
221 pub const MIN_PARALLEL_WORKERS: u8 = 2;
222
223 /// Minimum merge retries.
224 pub const MIN_MERGE_RETRIES: u8 = 1;
225}
226
227/// File paths and directory names.
228pub mod paths {
229 /// Session state filename.
230 pub const SESSION_FILENAME: &str = "session.jsonc";
231
232 /// Stop signal filename.
233 pub const STOP_SIGNAL_FILE: &str = "stop_requested";
234
235 /// Migration history file path.
236 pub const MIGRATION_HISTORY_PATH: &str = ".ralph/cache/migrations.jsonc";
237
238 /// Productivity stats filename.
239 pub const STATS_FILENAME: &str = "productivity.jsonc";
240
241 /// Ralph temp directory name.
242 pub const RALPH_TEMP_DIR_NAME: &str = "ralph";
243
244 /// Legacy prompt temp file prefix.
245 pub const LEGACY_PROMPT_PREFIX: &str = "ralph_prompt_";
246
247 /// Ralph temp file prefix.
248 pub const RALPH_TEMP_PREFIX: &str = "ralph_";
249
250 /// Worker prompt override path.
251 pub const WORKER_OVERRIDE_PATH: &str = ".ralph/prompts/worker.md";
252
253 /// Scan prompt override path.
254 pub const SCAN_OVERRIDE_PATH: &str = ".ralph/prompts/scan.md";
255
256 /// Task builder prompt override path.
257 pub const TASK_BUILDER_OVERRIDE_PATH: &str = ".ralph/prompts/task_builder.md";
258
259 /// Environment variable for raw dump mode.
260 pub const ENV_RAW_DUMP: &str = "RALPH_RAW_DUMP";
261
262 /// Environment variable for the runner actually used (set by Ralph when spawning runners).
263 /// Used for analytics tracking in task custom fields.
264 pub const ENV_RUNNER_USED: &str = "RALPH_RUNNER_USED";
265
266 /// Environment variable for the model actually used (set by Ralph when spawning runners).
267 /// Used for analytics tracking in task custom fields.
268 pub const ENV_MODEL_USED: &str = "RALPH_MODEL_USED";
269}
270
271/// Version constants for schemas and templates.
272pub mod versions {
273 /// README template version.
274 pub const README_VERSION: u32 = 6;
275
276 /// Session state schema version.
277 pub const SESSION_STATE_VERSION: u32 = 1;
278
279 /// Migration history schema version.
280 pub const HISTORY_VERSION: u32 = 1;
281
282 /// Productivity stats schema version.
283 pub const STATS_SCHEMA_VERSION: u32 = 1;
284
285 /// Execution history schema version.
286 pub const EXECUTION_HISTORY_VERSION: u32 = 1;
287
288 /// Template version string.
289 pub const TEMPLATE_VERSION: &str = "1.0.0";
290}
291
292/// Default values for models and configuration.
293pub mod defaults {
294 /// Default Gemini model name.
295 pub const DEFAULT_GEMINI_MODEL: &str = "gemini-3-flash-preview";
296
297 /// Default Claude model name.
298 pub const DEFAULT_CLAUDE_MODEL: &str = "sonnet";
299
300 /// Default Cursor model name.
301 pub const DEFAULT_CURSOR_MODEL: &str = "auto";
302
303 /// Opencode prompt file message.
304 pub const OPENCODE_PROMPT_FILE_MESSAGE: &str = "Follow the attached prompt file verbatim.";
305
306 /// Fallback message for Phase 2 final response.
307 pub const PHASE2_FINAL_RESPONSE_FALLBACK: &str = "(Phase 2 final response unavailable.)";
308
309 /// Git LFS pointer file prefix.
310 pub const LFS_POINTER_PREFIX: &str = "version https://git-lfs.github.com/spec/v1";
311
312 /// Redaction placeholder text.
313 pub const REDACTED: &str = "[REDACTED]";
314
315 /// Sentinel RFC3339 timestamp used only when formatting "now" fails.
316 ///
317 /// This value is intentionally "obviously wrong" in modern persisted data so
318 /// fallback usage is detectable during debugging/audits.
319 pub const FALLBACK_RFC3339: &str = "1970-01-01T00:00:00.000000000Z";
320
321 /// Default task ID width.
322 pub const DEFAULT_ID_WIDTH: usize = 4;
323}
324
325/// UI symbols and emoji.
326pub mod symbols {
327 /// Celebration sparkles emoji.
328 pub const SPARKLES: &str = "✨";
329
330 /// Streak fire emoji.
331 pub const FIRE: &str = "🔥";
332
333 /// Achievement star emoji.
334 pub const STAR: &str = "⭐";
335
336 /// Completion checkmark.
337 pub const CHECKMARK: &str = "✓";
338}
339
340/// Spinner animation frames.
341pub mod spinners {
342 /// Default braille spinner frames.
343 pub const DEFAULT_SPINNER_FRAMES: &[&str] = &["⠋", "⠙", "⠹", "⠸", "⠼", "⠴", "⠦", "⠧", "⠇", "⠏"];
344}
345
346/// Milestone and achievement thresholds.
347pub mod milestones {
348 /// Task count milestones for achievements.
349 pub const MILESTONE_THRESHOLDS: &[u64] = &[10, 50, 100, 250, 500, 1000, 2500, 5000];
350}
351
352/// AGENTS.md section requirements.
353pub mod agents_md {
354 /// Required sections in AGENTS.md.
355 pub const REQUIRED_SECTIONS: &[&str] =
356 &["Non-Negotiables", "Repository Map", "Build, Test, and CI"];
357
358 /// Recommended sections for a complete AGENTS.md.
359 pub const RECOMMENDED_SECTIONS: &[&str] = &[
360 "Non-Negotiables",
361 "Repository Map",
362 "Build, Test, and CI",
363 "Testing",
364 "Workflow Contracts",
365 "Configuration",
366 "Git Hygiene",
367 "Documentation Maintenance",
368 "Troubleshooting",
369 ];
370}
371
372/// Custom field keys for analytics/observability data.
373pub mod custom_fields {
374 /// Key for the runner actually used (observational, not intent).
375 pub const RUNNER_USED: &str = "runner_used";
376
377 /// Key for the model actually used (observational, not intent).
378 pub const MODEL_USED: &str = "model_used";
379}
380
381/// Error message templates for consistent error formatting.
382pub mod error_messages {
383 /// Config update instruction suffix.
384 pub const CONFIG_UPDATE_INSTRUCTION: &str = "Update .ralph/config.jsonc";
385
386 /// Template for invalid config value errors.
387 pub fn invalid_config_value(
388 field: &str,
389 value: impl std::fmt::Display,
390 reason: &str,
391 ) -> String {
392 format!("Invalid {field}: {value}. {reason}. Update .ralph/config.jsonc.")
393 }
394}
395
396/// Status classification keywords for theme/styling.
397pub mod status_keywords {
398 /// Keywords indicating error status.
399 pub const ERROR: &[&str] = &[
400 "error", "fail", "failed", "denied", "timeout", "cancel", "canceled",
401 ];
402
403 /// Keywords indicating in-progress/warning status.
404 pub const IN_PROGRESS: &[&str] = &[
405 "running",
406 "started",
407 "pending",
408 "queued",
409 "in_progress",
410 "working",
411 ];
412
413 /// Keywords indicating success status.
414 pub const SUCCESS: &[&str] = &[
415 "completed",
416 "success",
417 "succeeded",
418 "ok",
419 "done",
420 "finished",
421 ];
422}