fix(reset): refuse every registration during a reset and purge only ids owned by the row's folder (#78)

Review round 2 (codex):
- R1: register_job reads .mam/reset-in-progress under the registry lock and
  refuses while a reset of the workspace owning <ws>/.mam/jobs is live, so the
  public registry.py register CLI and the API no longer bypass the gate. The
  reset's precheck takes that lock once after publishing its marker, so a
  registration is either seen by it or refused. The reset's own create passes
  MAM_RESET_OWNER_PID; the remote runner refuses the dispatch.
- R2: before each purge the reset re-runs stop's revalidate check
  (verify_session_uuid) for a post-discovered id against the row's folder and
  skips the target (id not verified) when it does not verify.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-30 03:45:27 +09:00
1 parent 18ea5f6184
commit 548c6854ea
7 files changed
+312 -33

No files matched your search

@@ -92,7 +92,9 @@ _refuse_locked() {
# The update admission lock is taken exclusively, as update.sh does, while the
# reset publishes its markers: a delegate submit admitted earlier has written
# its job record (the precheck below sees it), and one admitted later sees
# .mam/reset-in-progress and refuses.
# .mam/reset-in-progress and refuses. Any other registration in .mam/jobs
# (registry.py register, the delegation API) reads the marker under the
# registry lock, which the precheck takes before it lists the open jobs.
mkdir -p "$MAM"
exec 7>>"$MAM/update-admission.lock"
case "$("$PY" -m lib_py.pane_lock acquire --fd 7 --wait-env MAM_UPDATE_ADMISSION_WAIT_S)" in
@@ -255,6 +257,11 @@ for target_name in ${ENTRY_NAMES[@]+"${ENTRY_NAMES[@]}"}; do
SKIPPED_ARGS+=(--skipped "$R_NAME:id_unverified")
continue
fi
if ! MAM_STATE_JSON="$STATE_JSON" "$PY" -m lib_py.reset id-owned --workspace "$WS" --session "$R_NAME"; then
echo "skipped $R_NAME: its recorded id $R_ROW_ID does not verify as a conversation of its folder, so it may be another folder's and nothing is purged; check it, purge it by hand if it is this agent's, and rerun the reset"
SKIPPED_ARGS+=(--skipped "$R_NAME:id_unverified")
continue
fi
echo "reset [$R_NAME]: ${STOP_CMD[*]} --purge-conversation --yes"
purge_rc=0
@@ -283,7 +290,8 @@ for target_name in ${ENTRY_NAMES[@]+"${ENTRY_NAMES[@]}"}; do
echo "reset [$R_NAME]: ${CREATE_CMD[*]}"
create_rc=0
"${CREATE_CMD[@]}" || create_rc=$?
# Its onboarding job is the one registration the reset marker lets through.
MAM_RESET_OWNER_PID="$$" "${CREATE_CMD[@]}" || create_rc=$?
if [ "$create_rc" -ne 0 ]; then
FAILED_SPEC="$R_NAME:create:$create_rc"
break