feat(issue-21): resume only at the original cwd; persist the control-plane binding on the already-running path; fail loudly when a worktree binding cannot be computed

- A11: resume refuses (exit 2) a --workspace other than the row's pane.cwd, and
  a pane.cwd that no longer exists (checked first: mam_abs_workspace returns a
  missing path unchanged). Before, claude/grok failed with a misleading "No
  saved session" and class A agents started a new conversation in the wrong
  directory. Rows without pane.cwd are not checked.
- A12 (recommendation 1): create and resume no longer swallow a failed binding
  computation. A worktree (--workspace != control root) is refused with exit 2
  and nothing spawned or recorded; the control root itself warns and records
  the row without control_plane.
- A13 (recommendation 2): resume computes the binding before the herdr-alive
  check, so the already-running path records it too (update_yaml_resumed.sh
  fills a missing field only). Pane forwarding and the whitespace refusal stay
  on the spawn path.

Tests W7-W9.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_017R3Eg7MEpSWnm1oB9ZPP6G
This commit is contained in:
GodopuandClaude Opus 5 committed 2026-09-14 15:24:10 +00:00
1 parent fadd38cf56
commit 2679ddfffd
3 files changed
+138 -15

No files matched your search

@@ -208,7 +208,20 @@ fi
# lib.sh splits those flags unquoted (and, with env flags, never reuses an
# idle pane - `agent start --` would pass them to the agent as arguments), so a
# binding with whitespace that would have to be forwarded is refused.
CP_JSON="$(mam_control_plane_json "$WORKSPACE" 2>/dev/null || true)"
# A binding that cannot be computed is not swallowed (Issue #21 phase 2, A12):
# for a worktree (--workspace != control root) that would silently put the
# session on the wrong control plane, so refuse; for the control root itself
# warn and record the row without control_plane.
cp_rc=0
CP_JSON="$(mam_control_plane_json "$WORKSPACE")" || cp_rc=$?
if [ "$cp_rc" -ne 0 ] || [ -z "$CP_JSON" ]; then
if [ "$(mam_abs_workspace "$WORKSPACE")" != "$(mam_abs_workspace "$WORKSPACE_ROOT")" ]; then
echo "ERROR: cannot compute the control-plane binding (rc=$cp_rc) for --workspace '$WORKSPACE' (control root '$WORKSPACE_ROOT'); refusing to start a session that would use the wrong control plane" >&2
exit 2
fi
echo "WARNING: control-plane binding unavailable (rc=$cp_rc); the row is recorded without control_plane" >&2
CP_JSON=""
fi
CP_PREFIX=""
if [ -n "$CP_JSON" ]; then
cp_rc=0