Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
50 changes: 50 additions & 0 deletions src/detect/manifest/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -733,6 +733,56 @@ fn codex_osc_title_plain_is_idle() {
assert!(result.visible_idle);
}

#[test]
fn codex_wrapped_model_capacity_error_is_blocked() {
let screen = "⚠ Selected model is at capacity. Please\n\
\x20\x20try a different model.\n\n\
› Summarize recent commits\n\n\
gpt-5.6-sol high · /work · Ready\n";
let result = osc_explain(Agent::Codex, screen, "project", "");

assert_eq!(result.state, AgentState::Blocked);
assert_eq!(
result.matched_rule.as_ref().map(|r| r.id.as_str()),
Some("model_capacity_blocked")
);
assert!(result.visible_blocker);
}

#[test]
fn codex_active_spinner_beats_stale_model_capacity_error() {
let screen = "⚠ Selected model is at capacity. Please\n\
\x20\x20try a different model.\n\n\
› Summarize recent commits\n\n\
gpt-5.6-sol high · /work · Working\n";
let result = osc_explain(Agent::Codex, screen, "⠋ project", "");

assert_eq!(result.state, AgentState::Working);
assert_eq!(
result.matched_rule.as_ref().map(|r| r.id.as_str()),
Some("osc_title_working")
);
assert!(result.visible_working);
assert!(!result.visible_blocker);
}

#[test]
fn codex_stale_model_capacity_error_remains_idle() {
let screen = "⚠ Selected model is at capacity. Please try a different model.\n\n\
• Explored\n\
└ Read Cargo.toml\n\n\
› Summarize recent commits\n\n\
gpt-5.6-sol high · /work · Ready\n";
let result = osc_explain(Agent::Codex, screen, "project", "");

assert_eq!(result.state, AgentState::Idle);
assert_eq!(
result.matched_rule.as_ref().map(|r| r.id.as_str()),
Some("osc_title_idle")
);
assert!(result.visible_idle);
}

#[test]
fn codex_background_terminal_screen_does_not_override_osc_idle() {
// Background terminal tasks can be long-lived helpers such as dev servers.
Expand Down
12 changes: 10 additions & 2 deletions src/detect/manifests/codex.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
id = "codex"
version = "2026.07.18.1"
version = "2026.08.05.1"
min_engine_version = 2
updated_at = "2026-07-18T00:00:00Z"
updated_at = "2026-08-05T00:00:00Z"

[[rules]]
id = "osc_title_blocked"
Expand All @@ -11,6 +11,14 @@ region = "osc_title"
visible_blocker = true
contains = ["Action Required"]

[[rules]]
id = "model_capacity_blocked"
Comment thread
coderabbitai[bot] marked this conversation as resolved.
state = "blocked"
priority = 490
region = "bottom_non_empty_lines(4)"

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

P1 Stale capacity error remains blocked

When a single-line capacity error is followed by exactly three newer non-empty lines, bottom_non_empty_lines(4) retains the stale error and the blocked rule outranks the static-title idle rule, causing an idle Codex pane to remain reported as blocked.

Knowledge Base Used: Agent detection, Ghostty integration, and configuration

Copy link
Copy Markdown

Choose a reason for hiding this comment

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

🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

🧩 Analysis chain

🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- manifest ---'
cat -n src/detect/manifests/codex.toml
printf '%s\n' '--- relevant tests ---'
sed -n '700,780p' src/detect/manifest/tests.rs
printf '%s\n' '--- related rules and helpers ---'
rg -n -C 3 'bottom_non_empty_lines|capacity|codex' src/detect
printf '%s\n' '--- repository changes ---'
git diff --stat
git status --short
printf '%s\n' '--- validation recipes ---'
if command -v just >/dev/null 2>&1; then just --list 2>/dev/null | sed -n '1,120p'; else echo 'just unavailable'; fi

Repository: herdrdev/herdr

Length of output: 50370


🏁 Script executed:

#!/bin/bash
set -eu
printf '%s\n' '--- capacity tests ---'
sed -n '760,790p' src/detect/manifest/tests.rs
printf '%s\n' '--- region implementation ---'
sed -n '1240,1345p' src/detect/manifest.rs
printf '%s\n' '--- region tests ---'
sed -n '520,550p' src/detect/manifest/tests.rs
printf '%s\n' '--- project requirement references ---'
rg -n -i -C 3 'bottom three|three-line|three lines|capacity error|model capacity|at capacity|codex' \
  README.md .github src tests 2>/dev/null | sed -n '1,240p'
printf '%s\n' '--- just recipe definition ---'
if [ -f justfile ]; then rg -n -C 3 '^check|check:' justfile; else echo 'justfile not found'; fi

Repository: herdrdev/herdr

Length of output: 22276


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
import re

screen = (
    "⚠ Selected model is at capacity. Please\n"
    "  try a different model.\n\n"
    "› Summarize recent commits\n\n"
    "gpt-5.6-sol high · /work · Ready\n"
)
pattern = re.compile(
    r"(?m)^⚠ Selected\s+model\s+is\s+at\s+capacity\.\s+Please\s+"
    r"a\s+different\s+model\.$"
)

def bottom_non_empty_lines(content, count):
    lines = content.splitlines()
    selected = [i for i, line in reversed(list(enumerate(lines)))
                if line.strip()][:count]
    return "" if not selected else "\n".join(lines[min(selected)]) + "\n" if False else \
        "\n".join(lines[min(selected):]) + "\n"

for count in (3, 4):
    region = bottom_non_empty_lines(screen, count)
    print(f"count={count}")
    print("region_lines=", repr(region.splitlines()))
    print("capacity_match=", bool(pattern.search(region)))
PY
printf '%s\n' '--- exact manifest diff ---'
git diff -- src/detect/manifests/codex.toml src/detect/manifest/tests.rs

Repository: herdrdev/herdr

Length of output: 517


🏁 Script executed:

#!/bin/bash
set -eu
python3 - <<'PY'
import re

screen = (
    "⚠ Selected model is at capacity. Please\n"
    "  try a different model.\n\n"
    "› Summarize recent commits\n\n"
    "gpt-5.6-sol high · /work · Ready\n"
)
pattern = re.compile(
    r"(?m)^⚠ Selected\s+model\s+is\s+at\s+capacity\.\s+"
    r"Please\s+try\s+a\s+different\s+model\.$"
)

def bottom_non_empty_lines(content, count):
    lines = content.splitlines()
    indices = [i for i, line in reversed(list(enumerate(lines)))
               if line.strip()][:count]
    return "" if not indices else "\n".join(lines[min(indices):]) + "\n"

for count in (3, 4):
    region = bottom_non_empty_lines(screen, count)
    print(f"count={count}")
    print("region_lines=", repr(region.splitlines()))
    print("capacity_match=", bool(pattern.search(region)))

stale = (
    "⚠ Selected model is at capacity. Please try a different model.\n\n"
    "• Explored\n"
    "└ Read Cargo.toml\n\n"
    "› Summarize recent commits\n\n"
    "gpt-5.6-sol high · /work · Ready\n"
)
for count in (3, 4):
    region = bottom_non_empty_lines(stale, count)
    print(f"stale_count={count}", "capacity_match=", bool(pattern.search(region)))
PY

Repository: herdrdev/herdr

Length of output: 560


Match the required three-line bottom window.

bottom_non_empty_lines(4) matches a warning with three newer non-empty lines. Use bottom_non_empty_lines(3) and update the wrapped fixture, or change the requirement to four lines. Run just check.

Source: Coding guidelines

visible_blocker = true
regex = ['(?m)^⚠ Selected\s+model\s+is\s+at\s+capacity\.\s+Please\s+try\s+a\s+different\s+model\.$']

[[rules]]
id = "osc_title_working"
state = "working"
Expand Down
12 changes: 10 additions & 2 deletions website/agent-detection/codex.toml
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
id = "codex"
version = "2026.07.18.1"
version = "2026.08.05.1"
min_engine_version = 2
updated_at = "2026-07-18T00:00:00Z"
updated_at = "2026-08-05T00:00:00Z"

[[rules]]
id = "osc_title_blocked"
Expand All @@ -11,6 +11,14 @@ region = "osc_title"
visible_blocker = true
contains = ["Action Required"]

[[rules]]
id = "model_capacity_blocked"
state = "blocked"
priority = 490
region = "bottom_non_empty_lines(4)"
visible_blocker = true
regex = ['(?m)^⚠ Selected\s+model\s+is\s+at\s+capacity\.\s+Please\s+try\s+a\s+different\s+model\.$']

[[rules]]
id = "osc_title_working"
state = "working"
Expand Down
Loading