fix(agents): pin post-discovered session ids on a verified completed; agy never takes another workspace's or session's conversation (Issue #40)

- BaseAgentAdapter: id_lifecycle (pre_assigned: claude, grok / post_discovered)
  and capture_active_session_id - exactly one verified candidate newer than the
  session that no other row records, else a reason (no-candidate, ambiguous, ...).
- agy: verify_artifact (discover) rejects an id last_conversations.json maps to
  another workspace and always excludes ids other rows record (a cache hit no
  longer bypasses it). capture uses the cache only as a proposal: the
  conversation's presence lock or DB must be held by the row's pane process or
  a descendant (lsof/ps); anything unprovable is not pinned.
- lib_py/agents/autopin.py: handle_completed, run by the side that verified the
  job's completed - the delegate-job wrapper (direct), create --onboard and the
  loop's wait_for_job (recovery, as a subprocess: G9). Local herdr jobs only;
  one (job, dispatch token, attempt) is handled once (job-scoped flock + marker
  in the job dir); writes go through atomic_dump_yaml; a pin records
  session_id_source=discovered / session_id_verified=true; a failure leaves the
  reason on the row and never changes the job's result.
- reconcile.sh drift C for agy, hermes, opencode and codex calls the same
  capture (the agy *.db glob is gone); _pin_and_verify_resume uses pin_row.
- Tests: tests/test_issue40_auto_pin.py; issue64 :407 now expects False; the
  static reconcile-source checks follow the move to the adapters; the two tier2
  drift-C component tests create with --no-onboard (onboarding now pins).

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
GodopuandClaude Opus 5.5 committed 2026-10-20 23:40:03 +09:00
1 parent ff8b381520
commit feccfd5e03
19 files changed
+1128 -338

No files matched your search

+12
View File
@@ -2467,6 +2467,18 @@ delegate_wait_terminal() {
--job "$job_id" --registry-dir "$reg_dir" --timeout "$timeout_s" --watch-pid "$$"
}
# delegate_autopin_completed <job_id> [dispatch_token] [registry_dir]
# Issue #40: once this side has seen the job `completed`, pin the session's
# post-discovered id (lib_py.agents.autopin decides and writes; remote, human
# and pre-assigned sessions are left alone, one job/token/attempt is handled
# once). Reports on stderr; never changes the job's result or this exit code.
delegate_autopin_completed() {
local job_id="$1" token="${2:-}" reg_dir="${3:-${MAM_JOBS_DIR:-${WORKSPACE_ROOT:-$PWD}/.mam/jobs}}"
PYTHONPATH="$SKILL_DIR:${PYTHONPATH:-}" HOME_DIR="${HOME_DIR:-$HOME}" LIB_SH="$SKILL_DIR/lib.sh" \
"$(_delegate_py_bin)" -m lib_py.agents.autopin --job "$job_id" --registry-dir "$reg_dir" \
--yaml "$AGENT_SESSIONS_YAML" ${token:+--expect-dispatch-token "$token"} >&2 || true
}
# delegate_onboard_exit <status>
# Issue #50: create's exit code for an onboarding status (0, 44 or 45).
delegate_onboard_exit() {