docs(issue-5): record the operator-authority transitions and the review fixes
state-transitions.md §3 gains the two rows it was missing. They are named transitions, not exceptions: re-dispatching a finished job to the next iteration and finalising an exhausted one are things the wrapper legitimately does, and they are gated on operator authority so an agent still cannot walk back its own terminal. The table also now states that a status may only be set by the request that owns it, which is what closes the metadata-merge bypass. phase2a-shadow.md documents the authority split, the CLI's new non-zero exit on a refused write, and why the audit mirror compares transition_seq. Two reviewer observations are carried forward as 2b work: `started` does not yet verify the assigned session, and stop_session's unconditional cancel is now refused on an already-completed job, which is the table behaving as designed but worth a release note. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01UrDNJkHmm18uu7n7JwV5Qd
This commit is contained in:
1 parent
56d08efa95
commit
3b134e3358
3 files changed
+23
-4
No files matched your search
@@ -1,6 +1,6 @@
|
||||
# 📑 Target State Transitions and CAS Specification
|
||||
|
||||
- **Document Version**: Rev.3 (Phase 2a 구현 매핑 추가)
|
||||
- **Document Version**: Rev.4 (운영자 권한 전이 2행 및 권한 축 추가 — 교차 리뷰 반영)
|
||||
- **Issue**: [Gitea Issue #5](https://git.godopu.com/tmpl/multi-agent-mux/issues/5)
|
||||
- **Scope**: Target Compare-And-Swap (CAS) State Machine & Attribution Contract
|
||||
|
||||
@@ -49,6 +49,12 @@ $$\text{Attribution Tuple} = (\text{job\_id}, \text{attempt\_id}, \text{agent\_s
|
||||
| `terminal` | 상충 신호 (`progress`/다른 Terminal) | 이미 Terminal 상태에 도달한 후 늦게 도착한 신호 | 기 커밋 상태 유지 | 상태 역행 및 덮어쓰기 거부, Conflict Audit Log 기록 |
|
||||
| 임의 상태 | Stale Attempt / Generation | 과거 시도 세대 또는 프로세스 세대 불일치 신호 | 전이 거부 | Stale Attempt 경고 기록 및 패킷 폐기 |
|
||||
| `running` | `deadline_timeout` | 작업 타임아웃 경과 및 실행 중단 확인 | `error` | 타임아웃 원인 기록 |
|
||||
| `terminal` | `redispatch` (**운영자 권한**) | 반복 위임(`--type loop\|discuss`)의 다음 회차 전달. `iteration`이 기존 값보다 **엄격히 증가**해야 함 | `pending` | 교차 리뷰 `68abd0ff` 보완. 재생(replay)은 iteration 미증가로 거부됨 |
|
||||
| `terminal` | `finalize` (**운영자 권한**) | 반복 예산 소진 시 워크플로 확정 | `error` | 교차 리뷰 `68abd0ff` 보완 |
|
||||
|
||||
> 🔑 **권한 축(Authority)**: `redispatch`·`finalize`는 `source ∈ {registry_cli, operator}`에서만 허용된다. 에이전트(`publish_event`)는 **자신의 terminal을 되돌릴 수 없다** — 이것이 CAS 표의 존재 이유이며, 위 두 행은 그 원칙의 예외가 아니라 래퍼가 수행하는 별개 전이를 이름 붙인 것이다.
|
||||
>
|
||||
> 🔑 **status는 요청으로만 설정된다**: 임의 필드로 실린 `status`는 경계 내부에서 거부된다(`progress`가 terminal을 커밋하는 우회 차단). 알 수 없는 요청명도 거부된다. `pending`도 소유 요청(`redispatch`)을 갖는다.
|
||||
|
||||
---
|
||||
|
||||
@@ -56,10 +62,10 @@ $$\text{Attribution Tuple} = (\text{job\_id}, \text{attempt\_id}, \text{agent\_s
|
||||
|
||||
| 계약 | 구현 | 테스트 |
|
||||
|---|---|---|
|
||||
| §3 CAS 전이표 | `lib_py/delegation/engine.py::_decide` (순수 함수, 락 안에서 호출) | `test_engine_*` |
|
||||
| §3 CAS 전이표 | `lib_py/delegation/engine.py::_decide` (순수 함수, 락 안에서 호출) | `test_engine_*`, `test_fa_*`, `test_r2_*`, `test_r3_*` |
|
||||
| 단일 전이 주체 | `engine.transition` — 유일한 상태 writer. `update_job_status`·`pick_pending`이 이를 경유 | `test_g6_every_record_writer_*` |
|
||||
| 락 내 I/O 배제 | 락 = 판정 + 레코드 1회 쓰기. 감사 mirror는 큐잉 후 락 밖 flush | `test_g5_no_blocking_io_*` |
|
||||
| §2 4중 귀속 | `lib_py/loop/attribution.py::check` | `test_attribution_*` |
|
||||
| §2 4중 귀속 | `lib_py/loop/attribution.py::check` + `policy.collect_observed_identity` (관측 식별자와의 대조) | `test_attribution_*`, `test_r1_*` |
|
||||
| 롤백 | `MAM_ENGINE_CAS=0` → 보존된 `_*_legacy` 본체 | 전 특성화 테스트 parametrize |
|
||||
|
||||
> 📌 **Phase 2a는 추론 완료를 커밋하지 않는다.** `inferred completed` 행은 `lib_py/loop/policy.py`가 `candidate_approved`로 **판정만** 하고, shadow 러너가 이를 로그로 남긴다. 실제 CAS 커밋 연동은 Phase 2b다.
|
||||
|
||||
Reference in new issue
Block a user