Files
multi-agent-mux/.agents/reports/canary-projects-multi-agent-mux-creator-cline/report-d629619a.md
T

9.0 KiB
Raw Blame History

Cross-Code Review Report: B-8 send_keys_safe agy Path Bypass Removal

Job ID: d629619a Reviewer: cline (session: herdr:canary-projects-multi-agent-mux-creator-cline) Review Target: B-8 send_keys_safe agy unconditional return 0 bypass removal and verification integrity cross-check Base Commit: f8bfa07 (clean tree except working changes) Date: 2026-08-13


1. Executive Summary

This review verifies the removal of the agy early return 0 bypass in send_keys_safe() and the addition of supporting input-region infrastructure (adapter properties, CLI bridge, input_region.py module). The change set includes 5 modified files and 2 new files.

Verdict: PASS — The core B-8 fix is correct: the agy unconditional return 0 is removed, and agy sessions now go through the C-m submission verification loop with hardened checks. The test confirms returncode 4 on submission failure (not 0). However, the supporting input_region.py module has a missing base.py property declaration that causes AttributeError (instead of the intended ValueError) for the hermes adapter. This is a latent bug in infrastructure not yet wired into send_keys_safe, so it does not affect the B-8 fix itself.


2. Change Set

File Change Lines
.agents/skills/lib.sh Remove agy early return 0; add agy to skip-paste-check group -6/+2
.agents/skills/lib_py/agents/__main__.py Add input-region CLI command + emit INPUT_* facts +15
.agents/skills/lib_py/agents/adapters/agy.py Add input_prompt/placeholder/rule_pattern +12
.agents/skills/lib_py/agents/adapters/claude.py Add input_prompt/placeholder/rule_pattern +12
.agents/skills/lib_py/agents/adapters/cline.py Add input_prompt/placeholder/rule_pattern +12
.agents/skills/lib_py/agents/input_region.py NEW: rule-based input region extraction +40
tests/test_b8_send_keys_verification.py NEW: bash mock test for agy submission failure +29

3. Core B-8 Fix Analysis (lib.sh)

Before (lines 1587-1591, removed):

if [[ "$sess" =~ "agy" ]]; then
  _sks_herdr send-keys -t "$sess" C-m
  return 0
fi

This was the B-8 bug: agy sessions blindly returned 0 (success) after sending C-m, without verifying submission.

After (line 1588):

if [[ "$sess" =~ "cline" ]] || [[ "$sess" =~ "claude" ]] || [[ "$sess" =~ "agy" ]]; then
  # Skip strict paste check due to scrollout false-positives, proceed to C-m submission loop
  true

agy is now grouped with cline/claude: paste visibility check is skipped (due to scrollout false-positives), but the session goes through the full C-m submission verification loop (lines 1607-1626). If submission is not accepted after 3 tries, return 4 is executed instead of return 0.

Verification: The test test_send_keys_safe_b8_verification mocks _pane_capture to return static content (no execution token, no pane change) and confirms send_keys_safe returns 4 with "Enter not accepted after 3 tries" in stderr.


4. Supporting Infrastructure Analysis

4.1 Adapter Properties (agy.py, claude.py, cline.py)

Each adapter now defines input_prompt, input_placeholder, and input_rule_pattern:

Adapter input_prompt input_placeholder input_rule_pattern
agy > `` ─{10,}
claude `` ─{10,}
cline Ask anything... ─{10,}

These are correct and consistent with the agent TUI input area layouts.

4.2 CLI Bridge (__main__.py)

New input-region command reads pane text from stdin and calls extract_input_region(). On success, prints region and exits 0. On exception, prints error to stderr and exits 5.

The facts command now also emits INPUT_PROMPT, INPUT_PLACEHOLDER, INPUT_RULE_PATTERN for shell evaluation.

Manual verification:

  • input-region agy with rule-delimited pane → outputs "test prompt", RC=0
  • input-region cline with multi-line + placeholder → outputs "line 1\nline 2\nmarker-xyz", RC=0
  • input-region hermes → outputs AttributeError message, RC=5 ⚠️ (see F-1)

4.3 input_region.py

Rule-based extraction: finds horizontal rule separators (─{10,}), extracts text between the last two rules (excluding rule lines themselves via lines[rule_indices[-2] + 1:rule_indices[-1]]), strips prompt tokens and placeholders.

Key design choices (correct):

  • Excludes rule lines from region: +1 offset on start index
  • Falls back to full lines when no rules found (supports mocks/unruled panes)
  • Checks not adapter.input_prompt for unsupported agent detection
  • Uses adapter.input_rule_pattern or r'─{10,}' fallback

4.4 Test (test_b8_send_keys_verification.py)

Bash mock test that sources lib.sh, mocks _pane_quiescent, _pane_dialog_open, _sks_herdr, and _pane_capture, then runs send_keys_safe for an agy session. Expects returncode 4 and "Enter not accepted after 3 tries" in stderr.

Note: _pane_tail is NOT mocked — it calls _pane_capture internally (line 1508), which IS mocked, so this works correctly.


5. Findings

F-1 (Medium) — Missing input_prompt/input_placeholder/input_rule_pattern in base.py

Location: .agents/skills/lib_py/agents/base.py (not modified) Observation: BaseAgentAdapter does not define input_prompt, input_placeholder, or input_rule_pattern properties. Only agy, claude, and cline adapters override them. HermesAgentAdapter inherits from BaseAgentAdapter without override. Impact: When input_region.py line 14 accesses adapter.input_prompt on a hermes adapter, it raises AttributeError: 'HermesAgentAdapter' object has no attribute 'input_prompt' instead of the intended ValueError("Agent 'hermes' has no input area facts"). The CLI bridge catches Exception broadly so it still exits with code 5, but the error message is unhelpful. Verified: hasattr(get_adapter('hermes'), 'input_prompt') returns False. Fix: Add to base.py:

@property
def input_prompt(self) -> Optional[str]:
    return None
@property
def input_placeholder(self) -> Optional[str]:
    return None
@property
def input_rule_pattern(self) -> Optional[str]:
    return None

Severity assessment: Medium — latent bug in new infrastructure. Does not affect the B-8 fix itself (d629619a's lib.sh does not call input-region), but will surface when the infrastructure is wired in.

F-2 (Low) — Usage string in __main__.py doesn't mention input-region

Location: .agents/skills/lib_py/agents/__main__.py:8 Observation: Usage string says Usage: python -m lib_py.agents <facts|resolve> [args...] but input-region is now a supported command. Fix: Update to Usage: python -m lib_py.agents <facts|resolve|input-region> [args...]

F-3 (Info) — input_region.py not wired into send_keys_safe

Observation: The input_region.py module and CLI bridge are added but not called from send_keys_safe(). The lib.sh change is purely the agy early-return removal. The infrastructure is prepared for future integration (as seen in the alternative 0d0147de implementation). Assessment: Acceptable incremental approach. The B-8 fix is self-contained.

F-4 (Info) — [A-Za-z]+ing fast-path regex retained

Location: .agents/skills/lib.sh:1614 Observation: The submission loop still uses grep -Eq "● |✽ |[A-Za-z]+ing" as a fast-path to return 0. This pattern can match false positives (any English word ending in "ing": "Running", "string", "thing", etc.). Assessment: Pre-existing issue, NOT introduced by this change. The 0d0147de alternative removes this fast-path. Non-blocking for d629619a.


6. Test Results

Test Result
test_b8_send_keys_verification.py::test_send_keys_safe_b8_verification PASS
test_a4_adapter_contract.py::test_resolve_home_contract PASS
test_a4_adapter_contract.py::test_agent_adapter_registry PASS
test_a4_adapter_contract.py::test_agent_of_row_priority PASS

Static Analysis

Check Result
bash -n .agents/skills/lib.sh PASS
py_compile all 6 Python files PASS
CLI input-region agy manual test PASS (RC=0, correct output)
CLI input-region cline manual test PASS (RC=0, correct output)
CLI input-region hermes manual test RC=5 but AttributeError (F-1)
flake8 Not available (non-blocking)

7. Conclusion

The B-8 fix correctly removes the agy unconditional return 0 bypass. agy sessions now go through the same C-m submission verification loop as cline and claude, with failure returning 4 instead of 0. The test validates this behavior.

The supporting input-region infrastructure (adapter properties, CLI bridge, input_region.py) is functionally correct for supported agents (agy, claude, cline) but has a missing base.py property declaration that causes AttributeError for hermes (F-1, Medium). This should be fixed before the infrastructure is wired into send_keys_safe.

No design-level rework or escalation is needed.

[VERDICT: PASS]