t1085: Fix AI reasoning — portable timeout for macOS cron#1640
t1085: Fix AI reasoning — portable timeout for macOS cron#1640marcusquinn merged 1 commit intomainfrom
Conversation
The AI reasoning engine was silently failing on every cycle because `timeout` (GNU coreutils) is not available in macOS cron environment. The command returned empty string via `|| echo ""`, making it look like the AI returned nothing. - Add portable_timeout() to _common.sh for all supervisor scripts - Add local fallback in ai-reason.sh for standalone execution - Prefers GNU timeout when available, falls back to background process + sleep + kill pattern - Returns 124 on timeout (matches GNU convention) This was the root cause of 17 consecutive 0-byte AI responses since Phase 14 went live.
Summary of ChangesHello @marcusquinn, I'm Gemini Code Assist1! I'm currently reviewing this pull request and will post my feedback shortly. In the meantime, here's a summary to help you and other reviewers quickly get up to speed! This pull request addresses a critical issue preventing the AI reasoning engine from functioning correctly in macOS cron environments. The core problem stemmed from the Highlights
Changelog
Activity
Using Gemini Code AssistThe full guide for Gemini Code Assist can be found on our documentation page, here are some quick tips. Invoking Gemini You can request assistance from Gemini at any point by creating a comment using either
Customization To customize Gemini Code Assist for GitHub experience, repository maintainers can create a configuration file and/or provide a custom code review style guide (such as PEP-8 for Python) by creating and adding files to a Limitations & Feedback Gemini Code Assist may make mistakes. Please leave feedback on any instances where its feedback is incorrect or counter productive. You can react with 👍 and 👎 on @gemini-code-assist comments. If you're interested in giving your feedback about your experience with Gemini Code Assist for Github and other Google products, sign up here. You can also get AI-powered code generation, chat, as well as code reviews directly in the IDE at no cost with the Gemini Code Assist IDE Extension. Footnotes
|
🔍 Code Quality Report�[0;35m[MONITOR]�[0m Code Review Monitoring Report �[0;34m[INFO]�[0m Latest Quality Status: �[0;34m[INFO]�[0m Recent monitoring activity: 📈 Current Quality Metrics
Generated on: Wed Feb 18 13:53:47 UTC 2026 Generated by AI DevOps Framework Code Review Monitoring |
|
There was a problem hiding this comment.
Code Review
The pull request introduces a portable_timeout function to handle command timeouts across macOS and Linux environments, addressing a critical bug where the AI reasoning engine failed on macOS due to the absence of the timeout command. The solution provides a fallback mechanism using background processes, sleep, and kill commands when GNU timeout is unavailable. The changes also integrate this new portable timeout into the ai-reason.sh script. Overall, the changes are well-implemented and directly address the identified issue, improving the robustness and cross-platform compatibility of the AI supervisor scripts. A minor point of feedback is to clarify the exit code mapping for SIGKILL and SIGTERM in the portable_timeout function.
| # If killed by our watchdog, return 124 (GNU timeout convention) | ||
| if [[ $exit_code -eq 137 || $exit_code -eq 143 ]]; then | ||
| return 124 |
There was a problem hiding this comment.
The portable_timeout function returns 124 for SIGKILL (137) and SIGTERM (143). While 124 is the GNU timeout convention for timeout, it's important to note that SIGKILL and SIGTERM are distinct signals. Returning 124 for both might obscure the specific signal that terminated the process. Consider distinguishing between SIGKILL and SIGTERM if there's a need for more granular error handling in consuming scripts, or add a comment explaining why both map to 124.
| # If killed by our watchdog, return 124 (GNU timeout convention) | |
| if [[ $exit_code -eq 137 || $exit_code -eq 143 ]]; then | |
| return 124 | |
| if [[ $exit_code -eq 137 || $exit_code -eq 143 ]]; then | |
| # Both SIGKILL (137) and SIGTERM (143) are mapped to 124 for GNU timeout compatibility. | |
| return 124 | |
| fi |
|
Caution Review failedThe pull request is closed. WalkthroughAdds a portable timeout mechanism for cross-platform shell script compatibility and introduces workload assessment logic to determine when AI reasoning should execute based on actionable work presence and cooldown intervals. Changes
Sequence DiagramsequenceDiagram
participant Supervisor
participant WorkloadCheck as has_actionable_work()
participant GitHub as GitHub API
participant LocalRepo as Local Repo
participant DB as Supervisor DB
participant ReasoningDecision as should_run_ai_reasoning()
participant AIEngine as AI Reasoning<br/>(opencode/claude)
participant Timeout as portable_timeout()
Supervisor->>ReasoningDecision: should_run_ai_reasoning(force?, repo_path)
ReasoningDecision->>WorkloadCheck: has_actionable_work(repo_path)
WorkloadCheck->>GitHub: Check issues/PRs
GitHub-->>WorkloadCheck: Issue count
WorkloadCheck->>LocalRepo: Check TODO flags
LocalRepo-->>WorkloadCheck: TODO count
WorkloadCheck->>DB: Query recent worker failures
DB-->>WorkloadCheck: Failure count
WorkloadCheck-->>ReasoningDecision: Aggregate workload count
ReasoningDecision->>ReasoningDecision: Check enablement & cooldown
ReasoningDecision-->>Supervisor: Decision (run or skip)
alt Should Run Reasoning
Supervisor->>Timeout: portable_timeout(interval, command)
Timeout->>AIEngine: Execute AI reasoning
AIEngine-->>Timeout: Result/Exit code
Timeout-->>Supervisor: Return code (124 if timeout)
end
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes Poem
✨ Finishing Touches
🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Comment |



Summary
The AI reasoning engine (Phase 14) has been running every ~35 minutes since going live but producing 0-byte responses on every single cycle (17 consecutive failures). Root cause:
timeoutis a GNU coreutils command not available in macOS cron environment.Root Cause
ai_result=$(timeout "$ai_timeout" opencode run ... 2>/dev/null || echo "")In cron,
timeoutis not found → command fails →|| echo ""catches it →ai_result=""→ "no parseable action plan" → logged as failure. Silent because stderr was redirected to/dev/null.Fix
portable_timeout()to_common.sh(shared by all supervisor scripts)timeoutwhen available (interactive shells, Linux)ai-reason.shfor standalone executionImpact
Phase 14 will start actually receiving AI responses on the next pulse cycle. The full intelligence upgrade (context building, reasoning, action planning) has been working correctly — only the final AI CLI invocation was broken.
Summary by CodeRabbit