Skip to content

t1085: Fix AI reasoning — portable timeout for macOS cron#1640

Merged
marcusquinn merged 1 commit intomainfrom
bugfix/t1085-timeout-fix
Feb 18, 2026
Merged

t1085: Fix AI reasoning — portable timeout for macOS cron#1640
marcusquinn merged 1 commit intomainfrom
bugfix/t1085-timeout-fix

Conversation

@marcusquinn
Copy link
Owner

@marcusquinn marcusquinn commented Feb 18, 2026

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: timeout is 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, timeout is 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

  • Add portable_timeout() to _common.sh (shared by all supervisor scripts)
  • Prefers GNU timeout when available (interactive shells, Linux)
  • Falls back to background process + sleep + kill pattern (macOS cron)
  • Returns 124 on timeout (matches GNU convention)
  • Local fallback in ai-reason.sh for standalone execution

Impact

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

  • New Features
    • Enhanced cross-platform timeout handling for improved reliability across different operating systems.
    • Intelligent task scheduling for AI reasoning based on workload detection and time-based intervals.

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.
@gemini-code-assist
Copy link

Summary of Changes

Hello @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 timeout command, a GNU coreutils utility, not being available, leading to silent failures and 0-byte AI responses. The solution involves implementing a robust, portable timeout mechanism that gracefully handles different operating system environments, ensuring the AI engine can now successfully process and generate responses.

Highlights

  • Portable Timeout Function: Introduced a new portable_timeout() function in _common.sh that provides a cross-platform timeout mechanism. It prioritizes the GNU timeout command when available (e.g., on Linux) and falls back to a background process, sleep, and kill pattern for environments where timeout is not present (e.g., macOS cron).
  • AI Reasoning Engine Fix: Resolved the issue where the AI reasoning engine (Phase 14) was producing 0-byte responses due to the timeout command being unavailable in macOS cron environments. The direct timeout calls in ai-reason.sh have been replaced with the newly implemented portable_timeout function.
  • Standalone Execution Support: Added a local fallback definition for portable_timeout within ai-reason.sh. This ensures that the script can execute correctly even when run standalone and _common.sh is not explicitly sourced, maintaining the timeout functionality.
Changelog
  • .agents/scripts/supervisor/_common.sh
    • Added a new shell function portable_timeout to provide a cross-platform timeout capability, preferring GNU timeout and falling back to a process management approach.
  • .agents/scripts/supervisor/ai-reason.sh
    • Integrated the portable_timeout function by replacing direct calls to the timeout command.
    • Included a local definition of portable_timeout to ensure the script's functionality when executed independently without sourcing _common.sh.
Activity
  • The AI reasoning engine (Phase 14) has been failing for 17 consecutive cycles, producing 0-byte responses.
  • The root cause was identified as the timeout command not being available in macOS cron environments.
  • This pull request introduces a fix to enable the AI engine to receive responses on its next pulse cycle.
Using Gemini Code Assist

The 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 /gemini <command> or @gemini-code-assist <command>. Below is a summary of the supported commands on the current page.

Feature Command Description
Code Review /gemini review Performs a code review for the current pull request in its current state.
Pull Request Summary /gemini summary Provides a summary of the current pull request in its current state.
Comment @gemini-code-assist Responds in comments when explicitly tagged, both in pull request comments and review comments.
Help /gemini help Displays a list of available commands.

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 .gemini/ folder in the base of the repository. Detailed instructions can be found here.

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

  1. Review the Privacy Notices, Generative AI Prohibited Use Policy, Terms of Service, and learn how to configure Gemini Code Assist in GitHub here. Gemini can make mistakes, so double check it and use code with caution.

@github-actions
Copy link

🔍 Code Quality Report

�[0;35m[MONITOR]�[0m Code Review Monitoring Report

�[0;34m[INFO]�[0m Latest Quality Status:
SonarCloud: 0 bugs, 0 vulnerabilities, 23 code smells

�[0;34m[INFO]�[0m Recent monitoring activity:
Wed Feb 18 13:53:44 UTC 2026: Code review monitoring started
Wed Feb 18 13:53:44 UTC 2026: SonarCloud - Bugs: 0, Vulnerabilities: 0, Code Smells: 23

📈 Current Quality Metrics

  • BUGS: 0
  • CODE SMELLS: 23
  • VULNERABILITIES: 0

Generated on: Wed Feb 18 13:53:47 UTC 2026


Generated by AI DevOps Framework Code Review Monitoring

@sonarqubecloud
Copy link

Copy link

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

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

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.

Comment on lines +128 to +130
# If killed by our watchdog, return 124 (GNU timeout convention)
if [[ $exit_code -eq 137 || $exit_code -eq 143 ]]; then
return 124

Choose a reason for hiding this comment

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

medium

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.

Suggested change
# 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

@marcusquinn marcusquinn merged commit 051af19 into main Feb 18, 2026
14 of 15 checks passed
@coderabbitai
Copy link
Contributor

coderabbitai bot commented Feb 18, 2026

Caution

Review failed

The pull request is closed.

Walkthrough

Adds 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

Cohort / File(s) Summary
Portable Timeout Implementation
.agents/scripts/supervisor/_common.sh
Introduces portable_timeout function providing GNU timeout fallback with watchdog-based termination for cross-platform compatibility. Handles signal cleanup and returns appropriate exit codes (124 for timeout).
AI Reasoning Workload Assessment
.agents/scripts/supervisor/ai-reason.sh
Adds workload assessment via has_actionable_work() (checks GitHub issues/PRs, local TODOs, recent failures) and should_run_ai_reasoning() decision logic. Replaces direct timeout invocations with portable_timeout for two AI execution paths.

Sequence Diagram

sequenceDiagram
    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
Loading

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~25 minutes

Poem

🔧 A timeout that roams cross-platform lands,
Workload signals from many hands,
Cooldown intervals guard the beat,
AI reasoning stands complete! ⚡
With portable grace and watchdog care,
DevOps excellence in the air! ✨

✨ Finishing Touches
  • 📝 Generate docstrings
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment
  • Commit unit tests in branch bugfix/t1085-timeout-fix

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.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

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