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:
1 parent
ff8b381520
commit
feccfd5e03
19 files changed
+1128
-338
No files matched your search
@@ -34,6 +34,7 @@ MAM은 에이전트별 동작 특성(TUI 프롬프트 패턴, 세션 복원 인
|
||||
│ │ • input_prompt, input_placeholder, input_rule_pattern │ │
|
||||
│ │ • artifact_path(), verify_artifact(), purge_artifacts() │ │
|
||||
│ │ • spawn_spec(), resume_spec(), auth_ok(), discover() │ │
|
||||
│ │ • id_lifecycle, capture_active_session_id() (Issue #40) │ │
|
||||
│ └────────────────────────────────────────────────────────────────┬─────────────────────────────────────────────────────────────────┘ │
|
||||
│ │ │
|
||||
│ ┌────────────────────┬───────────────────────────────┬───────────────────────────────┬─────────────────────┐ │
|
||||
@@ -70,7 +71,7 @@ MAM은 에이전트별 동작 특성(TUI 프롬프트 패턴, 세션 복원 인
|
||||
|
||||
import os
|
||||
from typing import Any, List, Optional
|
||||
from ..base import BaseAgentAdapter, DiscoveryContext
|
||||
from ..base import BaseAgentAdapter, DiscoveryContext, PRE_ASSIGNED
|
||||
|
||||
|
||||
class GrokAgentAdapter(BaseAgentAdapter):
|
||||
@@ -169,8 +170,19 @@ class GrokAgentAdapter(BaseAgentAdapter):
|
||||
def discover(self, ctx: DiscoveryContext) -> List[str]:
|
||||
"""디스크의 세션 저장소에서 워크스페이스와 일치하는 세션 UUID 목록 탐색"""
|
||||
return []
|
||||
|
||||
# =========================================================================
|
||||
# 세션 ID 라이프사이클 (Issue #40)
|
||||
# =========================================================================
|
||||
@property
|
||||
def id_lifecycle(self) -> str:
|
||||
"""PRE_ASSIGNED: 기동 시 --session-id 로 ID 를 넘긴다 (claude, grok).
|
||||
POST_DISCOVERED(기본값): 첫 턴 뒤 디스크에 생긴 ID 를 찾는다 (agy, opencode, codex, hermes)."""
|
||||
return PRE_ASSIGNED
|
||||
```
|
||||
|
||||
**세션 ID 자동 확정 (Issue #40)**: `POST_DISCOVERED` 어댑터는 `capture_active_session_id(ctx)` 를 제공합니다. 기본 구현은 `discover()` 후보 중 `verify_session_uuid` 를 통과하고 다른 행이 기록하지 않은 것이 **정확히 하나**일 때만 `capture_result('captured', session_id=...)` 를 돌려주고, 아니면 `no-candidate` / `ambiguous` 등 이유를 돌려줍니다(읽기 전용). 후보 출처가 하나의 값만 주는 경우(agy 의 cwd 캐시처럼)에는 이 유일성이 아무것도 증명하지 못하므로, 그 어댑터는 이 메서드를 재정의해 소유를 따로 증명해야 합니다(agy: presence lock 을 쥔 프로세스가 그 행의 pane 프로세스 또는 자손). 실제 기록은 `completed` 를 검증한 수신 측(`lib_py.agents.autopin`: 위임 래퍼, `create --onboard`, 루프의 잡 대기)과 reconcile drift C 가 같은 판정으로 하며, 어댑터는 YAML/SQLite 에 쓰지 않습니다.
|
||||
|
||||
---
|
||||
|
||||
### Step 2: 어댑터 레지스트리 등록 (`.agents/skills/lib_py/agents/registry.py`)
|
||||
|
||||
Reference in new issue
Block a user