fix(delegate): submit also takes the target workspace's update admission (Issue #72, review R1)

Decision 8: delegate submit uses the admission lock of the workspace the
target session belongs to. The wrapper resolved only its own
WORKSPACE_ROOT, so a job could be registered and delivered to an agent of
another installed workspace while that workspace was being updated.

lib_py.update target-workspace resolves a herdr:<name> row's workspace (the
.mam at or above its pane.cwd, else its control_plane.workspace_root);
mam_update_admit takes an fd, and submit holds the caller root on fd 7 and
the target on fd 8 until the record is written. Rowless and remote targets
keep the caller-root gate.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-27 08:15:23 +00:00
1 parent 595e34b2d1
commit e3394655b3
4 files changed
+123 -16

No files matched your search

+10 -9
View File
@@ -3264,26 +3264,27 @@ mam_control_plane_prefix() {
# fd 7 (`7>&-` on such a child, as pane_lock's fd 9). The wait is bounded by
# MAM_UPDATE_ADMISSION_WAIT_S (default 120).
#
# mam_update_admit [workspace]: rc 0 admitted (fd 7 held, unless the workspace
# has no .mam), 1 refused (stderr).
# mam_update_admit [workspace [fd]]: rc 0 admitted (fd 7, or the given one,
# held unless the workspace has no .mam), 1 refused (stderr). Delegate submit
# also takes its target's workspace on fd 8.
mam_update_admit() {
local root="${1:-$WORKSPACE_ROOT}"
local root="${1:-$WORKSPACE_ROOT}" fd="${2:-7}"
local lock="$root/.mam/update-admission.lock" marker="$root/.mam/update-in-progress" st
# No .mam: not an installed workspace, which is all the update runs in (and a
# checkout running its own scripts gets no .mam from this).
[ -d "$root/.mam" ] || return 0
if ! exec 7>>"$lock"; then
if ! eval "exec $fd>>\"\$lock\""; then
echo "ERROR: cannot open the update admission lock $lock" >&2
return 1
fi
case "$(PYTHONPATH="$SKILL_DIR:${PYTHONPATH:-}" python3 -m lib_py.pane_lock acquire --fd 7 --shared --wait-env MAM_UPDATE_ADMISSION_WAIT_S)" in
case "$(PYTHONPATH="$SKILL_DIR:${PYTHONPATH:-}" python3 -m lib_py.pane_lock acquire --fd "$fd" --shared --wait-env MAM_UPDATE_ADMISSION_WAIT_S)" in
locked) ;;
timeout)
exec 7>&-
mam_update_admit_release "$fd"
echo "ERROR: an update of $root holds its admission lock (MAM_UPDATE_ADMISSION_WAIT_S passed); try again when it has finished" >&2
return 1 ;;
*)
exec 7>&-
mam_update_admit_release "$fd"
echo "ERROR: the update admission lock $lock could not be decided (lib_py.pane_lock)" >&2
return 1 ;;
esac
@@ -3296,11 +3297,11 @@ mam_update_admit() {
echo "NOTE: stale update marker $marker (its update is gone); ignored" >&2
return 0 ;;
esac
exec 7>&-
mam_update_admit_release "$fd"
echo "ERROR: an update of $root is in progress (marker $marker, holder $st); try again when it has finished" >&2
return 1
}
mam_update_admit_release() {
exec 7>&-
eval "exec ${1:-7}>&-"
}