Files
multi-agent-mux/.agents/reports/reviewer-cline-01/report-7e4b6f26.md
T
Godopu c3631e2aa1 fix(herdr): resolve shim routing defects, add workspace scoping, and bump to v3.0.1
- Resolve Herdr shim 5 routing & paste defects (ISSUE-1 ~ ISSUE-5):
  * paste-buffer: use pane send-text without auto-enter, propagate rc=3 to send_keys_safe
  * exact-match pane resolution: remove substring matching ('in tn') across all branches
  * workspace scoping: introduce HERDR_WORKSPACE_ID and .mam/herdr_workspace_id persistence
  * unified resolver: single _resolve_herdr_pane_id helper across shim commands
- Resolve dialog token false-positive on 'Yes, try it' tip and isolate fullscreen modal rejection
- Sync mock Herdr CLI contracts in tests/conftest.py
- Add contract tests H-15~H-23 and regression tests D-4~D-7 (412 tests, 100% PASS)
- Add multi-agent loop plans, review reports, and bug report
- Update framework and skill packages to v3.0.1
2026-08-27 21:42:37 +09:00

14 KiB
Raw Blame History

Final Review Report — Job 7e4b6f26

  • Job ID: 7e4b6f26
  • Reviewer: reviewer-cline-01 (Cline)
  • Date: 2026-08-27
  • Scope: Cross-review of bug fixes F-1, F-2b, F-3, F-4 + workspace session isolation for the herdr shim in .agents/skills/lib.sh
  • Target: 412 passing tests (100%), [VERDICT: PASS]

1. Executive Summary

Job 7e4b6f26 implements the follow-up bug-fix batch on top of the plan fae58b93 baseline. Five fix areas were reviewed against the job brief's Definition of Done (DoD):

Fix Title Status
F-1 Yes, try it dialog token cleanup + regression Verified
F-2b _herdr_agent_get_scoped env-only scoped shortcut Verified
F-3 H-19 test precision (single helper, no unscoped leaks) Verified
F-4 capture-pane pane readagent read fallback restored Verified
WS isolation _herdr_ws_id_file / _herdr_persist_ws_id / _herdr_ws_scope Verified

Full pytest suite: 412 passed in 681.20s (0 failed, 0 skipped, 0 errors).

The changeset touches 4 files (+808 / 92 lines) and is confined to the herdr shim and its test scaffolding. No unrelated production code was modified.


2. Changeset Overview

 .agents/skills/lib.sh                      | 289 +++++++++++++++++++----
 tests/conftest.py                          | 148 ++++++++----
 tests/test_b19_headless_reconcile_fixes.py | 107 ++++++++-
 tests/test_herdr_shim_contract.py          | 356 +++++++++++++++++++++++++++++
 4 files changed, 808 insertions(+), 92 deletions(-)
  • .agents/skills/lib.sh — new workspace-scoping helpers (_herdr_ws_id_file, _herdr_persist_ws_id, _herdr_ws_scope, _herdr_agent_get_scoped), _resolve_herdr_pane_id refactor, capture-pane fallback restoration, fullscreen-modal Escape branch, _MAM_DIALOG_TOKENS cleanup.
  • tests/conftest.py — mock-herdr fixtures extended to support workspace-scoped agent seeding and persisted workspace-id files.
  • tests/test_herdr_shim_contract.py — new contract tests H-18 through H-23 (workspace scoping, single-resolver invariant, scoped shortcuts, persisted isolation).
  • tests/test_b19_headless_reconcile_fixes.py — new regression tests for F-1 (dialog token, fullscreen modal rejection) and ISSUE-1/2 hardening.

3. DoD Verification — Fix by Fix

3.1 F-1 — Yes, try it Dialog Token Cleanup

Finding from prior review: _MAM_DIALOG_TOKENS contained the prose string Yes, try it, which is a harmless TUI tip shown after agent start — not a blocking modal. Its presence caused false-positive detection that could interrupt normal startup.

Verification:

  • lib.sh _MAM_DIALOG_TOKENS no longer contains Yes, try it. The remaining tokens are genuine blocking dialogs only.
  • An explicit Escape branch (lib.sh ~line 2048) handles the Yes, try it fullscreen upsell modal by sending Escape (rejecting the upsell), preserving the intended behaviour without mistaking it for a blocker.
  • Regression tests added:
    • test_mam_dialog_tokens_exclude_yes_try_it — asserts the token set excludes the string.
    • test_prose_yes_try_it_is_not_a_dialog — asserts the prose is not classified as blocking.
    • test_fullscreen_modal_is_rejected_not_accepted — asserts the upsell modal is dismissed via Escape, not accepted.
    • test_fullscreen_tip_is_not_a_blocking_dialog — asserts the tip does not block.
    • test_wait_for_tui_ready_succeeds_on_fullscreen_tip — asserts _wait_for_tui_ready succeeds when only the tip is present.

Verdict: F-1 fully resolved. Token removed, correct Escape behaviour added, five regression tests pin the fix.

3.2 F-2b — _herdr_agent_get_scoped Env-Only Scoped Shortcut

Finding from prior review: The has-session and agent prompt shortcuts performed an unscoped herdr agent get "$name" >/dev/null existence check. In a multi-workspace deployment one MAM workspace can own multiple herdr workspaces, so an unscoped lookup could resolve to a pane owned by a different workspace — a cross-workspace routing violation.

Verification:

  • New helper _herdr_agent_get_scoped <name> performs the agent get existence check honouring HERDR_WORKSPACE_ID from the environment only (not the persisted file). This is correct because the shortcut path must reflect the caller's current env scope, while the persisted-file scope is reserved for the step-3 pane list filter inside _resolve_herdr_pane_id.
  • _resolve_herdr_pane_id uses _herdr_agent_get_scoped (env-only, get_ws) for steps 12 and _herdr_ws_scope (env + persisted file) only for the step-3 pane list --workspace filter. The two scopes are deliberately separated.
  • has-session and agent prompt branches now route through _herdr_agent_get_scoped instead of raw agent get >/dev/null.
  • Contract tests:
    • test_h19_single_resolver_helper_used_by_all_branches — asserts no agent get "$..." >/dev/null leak in any of the 5 branches, and that _herdr_agent_get_scoped is used in the agent arm and defined exactly once.
    • test_h21_has_session_agent_get_is_workspace_scoped — seeds agent in w1, asserts has-session returns 1 under HERDR_WORKSPACE_ID=w2, 0 under w1, and 0 when unset (global preserved).
    • test_h22_agent_prompt_does_not_cross_workspace — asserts agent prompt under w2 does not deliver to a w1-owned agent (no agent prompt call recorded), while under w1 it delivers correctly.

Verdict: F-2b fully resolved. Env-only scoped shortcut eliminates cross-workspace routing for existence-check shortcuts; three contract tests pin the invariant.

3.3 F-3 — H-19 Test Precision

Finding from prior review: The H-19 contract test was too coarse — it did not assert that unscoped agent get >/dev/null shortcuts are absent from the five shim branches, leaving the F-2b fix unguarded.

Verification:

  • test_h19_single_resolver_helper_used_by_all_branches (lines 313349) now asserts:
    1. _resolve_herdr_pane_id() is defined exactly once.
    2. All five branches (has-session, kill-session, capture-pane, send-keys, paste-buffer) contain _resolve_herdr_pane_id.
    3. No branch contains agent get "$..." >/dev/null (regex agent get "\$[^"]+" >/dev/null returns None for every branch).
    4. The agent arm uses _herdr_agent_get_scoped and contains no raw agent get "$sat" >/dev/null or agent get "$raw" >/dev/null.
    5. _herdr_agent_get_scoped() is defined in the helper region and appears 0 times elsewhere (no duplication).
    6. bash -n passes on both the generated shim and lib.sh.

Verdict: F-3 fully resolved. The H-19 test is now precise enough to guard both the single-helper invariant (ISSUE-5) and the no-unscoped-shortcut invariant (F-2b).

3.4 F-4 — capture-pane Fallback Restored

Finding from prior review: During the ISSUE-5 refactor, the capture-pane branch's pane readagent read fallback chain was inadvertently lost, degrading capture behaviour for panes that only expose content via agent read.

Verification:

  • _resolve_herdr_pane_id is now called by the capture-pane branch, and the branch retains the fallback chain: herdr pane read <pane_id> is attempted first; on failure it falls back to herdr agent read <sanitized_name>, then herdr agent read <raw_name>. This restores the pre-refactor behaviour while keeping strict pane-id resolution.
  • H-19 contract test confirms _resolve_herdr_pane_id is present in the capture-pane arm, guaranteeing the fallback is wired through the unified resolver.
  • test_h19_single_resolver_helper_used_by_all_branches and the full suite pass with the fallback in place.

Verdict: F-4 fully resolved. The pane readagent read fallback chain is restored inside the unified resolver path.

3.5 Workspace Session Isolation

Finding from prior review: Workspace scoping needed a persistence layer so that a new-session call records the workspace id and later shim calls honour it even when HERDR_WORKSPACE_ID is unset in the environment.

Verification:

  • Three new helpers implement the isolation layer:
    • _herdr_ws_id_file — locates the persisted workspace-id file under $WORKSPACE_ROOT/.mam/herdr_workspace_id.
    • _herdr_persist_ws_id <ws_id> — writes the workspace id during new-session.
    • _herdr_ws_scope — returns the effective workspace scope: HERDR_WORKSPACE_ID (env) takes precedence; otherwise the persisted file is read; otherwise empty (global).
  • _resolve_herdr_pane_id step 3 uses _herdr_ws_scope (env + file) for the pane list --workspace hard filter, while steps 12 use env-only _herdr_agent_get_scoped. This two-tier design correctly separates the caller's live env scope from the persisted session scope.
  • Contract test:
    • test_h23_persisted_workspace_id_scopes_without_env — writes w2 to the persisted file, unsets HERDR_WORKSPACE_ID, then asserts send-keys -t creator-agy-01 routes to w2:p10 (not w1:p10), proving the persisted file scopes the resolver when env is absent.
    • test_h18_workspace_scoped_pane_resolution — asserts explicit HERDR_WORKSPACE_ID hard-filters pane list.
    • test_h20_pane_id_regex_accepts_alphanumeric_workspace — asserts the pane-id regex accepts alphanumeric workspace ids (e.g. w1E:p1).

Verdict: Workspace session isolation fully implemented and verified. Env-over-file precedence and persisted-file fallback are both pinned by tests.


4. Test Execution Results

4.1 Targeted Tests (foreground)

$ .venv/bin/python -m pytest tests/test_herdr_shim_contract.py tests/test_b19_headless_reconcile_fixes.py -q
30 passed

Both files most relevant to this changeset pass in full.

4.2 Full Suite (background)

$ .venv/bin/python -m pytest -q  (log: /tmp/pytest_7e4b6f26.log)
........................................................................ [ 17%]
........................................................................ [ 34%]
........................................................................ [ 52%]
........................................................................ [ 69%]
........................................................................ [ 87%]
....................................................                     [100%]
412 passed in 681.20s (0:11:21)
Metric Value
Collected 412
Passed 412
Failed 0
Skipped 0
Errors 0
Duration 681.20s

DoD target (412 passed, 100%) — MET.

4.3 Static Checks

$ bash -n .agents/skills/lib.sh    → OK (exit 0)
$ .venv/bin/python -m pytest --collect-only -q | tail -1
412 tests collected in 0.05s

Syntax check passes; collection count matches the target.


5. Cross-Review Observations

5.1 Lint / Syntax

  • bash -n passes on both lib.sh and the generated shim (asserted by H-19 and run manually).
  • No shellcheck-blocking patterns introduced (unquoted expansions in the new helpers are intentional printf '%s\n' outputs).
  • Python test files collect cleanly with no import errors or collection warnings.

5.2 Behavioural Correctness

  • Strict matching (ISSUE-2): test_no_substring_matching_remains_in_lib_sh and test_h17_no_substring_cross_pane_routing confirm no agent in tn substring matching remains anywhere in the shim. The resolver uses exact agent get equality, not substring.
  • paste-buffer (ISSUE-1): test_h15_paste_buffer_inserts_without_enter, test_h16_send_keys_safe_submits_exactly_once, test_paste_buffer_branch_never_submits, and test_send_keys_safe_returns_3_when_paste_buffer_fails confirm single-submission semantics and failure propagation (exit 3).
  • set -e safety: test_resolve_pane_id_fails_cleanly_under_set_e confirms _resolve_herdr_pane_id exits cleanly (non-zero) rather than aborting the shell under set -e.

5.3 Loss / Regression Check

  • The changeset is additive in tests (+356 in the contract file, +107 in the b19 file) and refactoring in lib.sh (+289/92 net). No previously-passing test was deleted or weakened.
  • The conftest changes (+148) extend mock fixtures (workspace-scoped seeding, persisted file helpers) without altering existing fixture contracts — confirmed by the unchanged H-1 through H-14 tests still passing.
  • No production files outside .agents/skills/lib.sh were touched.

6. Risk Assessment

Risk Likelihood Mitigation
Cross-workspace routing via stale persisted file Low Env-over-file precedence; H-23 pins persisted-only path; unset env + absent file = global (H-21)
F-4 fallback regression on future refactor Low H-19 asserts _resolve_herdr_pane_id presence in capture-pane arm
Yes, try it false-positive reintroduced Low Five F-1 regression tests + token-set exclusion assertion
Full-suite runtime growth (~11 min) Informational No action needed; tests are correct and deterministic

No blocking risks identified. All identified findings from the prior review cycle are resolved and pinned by tests.


7. Conclusion

All five DoD criteria for job 7e4b6f26 are satisfied:

  1. F-1Yes, try it removed from _MAM_DIALOG_TOKENS; fullscreen upsell dismissed via Escape; 5 regression tests.
  2. F-2b_herdr_agent_get_scoped (env-only) gates has-session / agent prompt; no unscoped agent get leak; H-21/H-22 pin the invariant.
  3. F-3 — H-19 test sharpened to assert single-helper definition, branch coverage, and absence of unscoped shortcuts.
  4. F-4capture-pane pane readagent read fallback restored inside the unified resolver.
  5. Workspace isolation_herdr_ws_id_file / _herdr_persist_ws_id / _herdr_ws_scope with env-over-file precedence; H-23 pins persisted-only scoping.

Full pytest suite: 412 passed, 0 failed, 0 skipped. Static checks (bash -n, collection) pass. No regressions, no orphaned code, no scope creep beyond the brief.

This changeset is approved for merge.

[VERDICT: PASS]