fix(loop): resolve O-2 atomic race-free lock and marker ownership release guard (22/22 PASS)

This commit is contained in:
2026-08-11 12:30:16 +09:00
parent f8084cd927
commit c7df7ffd68
7 changed files with 577 additions and 27 deletions
@@ -12,6 +12,8 @@ REPO_ROOT="$(cd "$SCRIPT_DIR/../../../.." && pwd)"
source "$REPO_ROOT/.agents/skills/lib.sh"
# shellcheck disable=SC1091
source "$REPO_ROOT/.agents/skills/multi-agent-mux-loop/scripts/diff_collect.sh"
# shellcheck disable=SC1091
source "$REPO_ROOT/.agents/skills/multi-agent-mux-loop/scripts/loop_lock.sh"
# Default configuration parameters
PLAN_MODE=false
@@ -82,13 +84,8 @@ if [ -z "$TARGET_AGENT" ] || [ -z "$TASK" ]; then
usage
fi
MAM_LOOP_MARKER="$REPO_ROOT/.mam/loop-guard-active"
mkdir -p "$(dirname "$MAM_LOOP_MARKER")"
_mam_lstart() { ps -p "$1" -o lstart= 2>/dev/null | tr -s ' ' | sed 's/^ *//;s/ *$//'; }
printf 'pid=%s\nlstart=%s\nstarted=%s\n' \
"$$" "$(_mam_lstart $$)" "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "$MAM_LOOP_MARKER"
_mam_release_guard() { rm -f "$MAM_LOOP_MARKER"; }
trap _mam_release_guard EXIT INT TERM HUP
MAM_LOOP_MARKER="${MAM_LOOP_MARKER:-$REPO_ROOT/.mam/loop-guard-active}"
_mam_release_guard() { mam_release_loop_lock "$MAM_LOOP_MARKER" || true; }
delegate_job_safe() {
local orig_script="$REPO_ROOT/.agents/skills/multi-agent-mux-delegate-job/multi-agent-mux-delegate-job"
@@ -119,6 +116,25 @@ log_error() {
echo -e "\033[1;31m[✗]\033[0m $1"
}
_mam_acquire_rc=0
mam_acquire_loop_lock "$MAM_LOOP_MARKER" || _mam_acquire_rc=$?
case "$_mam_acquire_rc" in
0) ;;
3)
_holder_pid=$(_mam_lock_field "$MAM_LOOP_MARKER" "pid" 2>/dev/null || echo "unknown")
log_error "Another multi-agent-mux-loop is already running in this workspace."
log_error " holder PID: $_holder_pid"
log_error " refusing to start a second loop (SQLite/YAML would race)."
exit 1
;;
*)
log_error "Cannot determine whether another loop is running (ps unavailable?)."
log_error " refusing to start rather than risk two loops writing the registry."
exit 1
;;
esac
trap _mam_release_guard EXIT INT TERM HUP
# --all-reviewer silently takes precedence over an explicit --reviewer list;
# warn so the discarded list isn't mistaken for having been honored (P2-1).
if [ "$ALL_REVIEWERS" = true ] && [ -n "$REVIEWER_LIST" ]; then