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
@@ -24,6 +24,15 @@
|
||||
|
||||
Shadow 러너는 애초에 쓰기 경로가 없으므로 **프로세스 종료만으로 흔적이 사라진다.** `.mam/shadow/`는 레지스트리와 분리되어 있어 삭제해도 job 상태에 영향이 없다.
|
||||
|
||||
## 2-1. 권한 구분 (교차 리뷰 반영)
|
||||
|
||||
| source | 할 수 있는 것 | 할 수 없는 것 |
|
||||
|---|---|---|
|
||||
| `publish_event` (에이전트) | 자신의 작업을 `running`/`completed`/`error`/`cancelled`로 전이 | **terminal을 되돌리는 것** (`redispatch`/`finalize` 거부) |
|
||||
| `registry_cli` (래퍼·운영자) | 위 전부 + `redispatch`(terminal→`pending`, iteration 증가 필수) + `finalize`(terminal→`error`) | iteration을 되돌리는 재생 |
|
||||
|
||||
**CLI 종료 코드 변경**: `registry.py status`/`update`가 CAS에 의해 거부되면 이제 **stderr에 사유를 내고 non-zero(4)** 로 종료한다. Phase 2a 이전에는 거부가 불가능해 항상 0이었고, 그 침묵이 반복 위임이 조용히 깨진 것을 감췄다.
|
||||
|
||||
## 3. 락 규율 (P2A-01)
|
||||
|
||||
```
|
||||
@@ -31,7 +40,7 @@ with registry_lock: 판정 + 레코드 1회 쓰기 + 알림 큐잉 ←
|
||||
락 해제 후: 감사 로그 flush, 발행 등 느린 작업
|
||||
```
|
||||
|
||||
감사 mirror가 락 밖으로 나가면서 순서 보장을 잃을 수 있으므로, 전이마다 단조 증가하는 `transition_seq`를 레코드와 알림에 함께 실어 늦게 도착한 flush도 순서를 복원할 수 있게 했다. 이 형태는 새로 만든 것이 아니라 `pick_pending`이 이미 쓰던 패턴을 모든 전이로 일반화한 것이다.
|
||||
감사 mirror가 락 밖으로 나가면서 순서 보장을 잃을 수 있으므로, 전이마다 단조 증가하는 `transition_seq`를 레코드와 알림에 함께 싣는다. **`update_logged_status`는 기존 `status.json`의 `transition_seq`가 더 크거나 같으면 쓰기를 건너뛴다** — 지연된 flush가 최신 상태를 되돌리지 못하게 하는 것이며, 락이 공짜로 주던 순차 일관성을 복원한다(교차 리뷰 F-B). 이 형태는 새로 만든 것이 아니라 `pick_pending`이 이미 쓰던 패턴을 모든 전이로 일반화한 것이다.
|
||||
|
||||
## 4. `herdr agent wait` 사용 규칙
|
||||
|
||||
@@ -61,3 +70,5 @@ Phase 0의 7종 + Phase 2a의 5종 = **12종**이 `expected_policy.decision`으
|
||||
2. `policy.decide`의 `candidate_approved`를 `engine.transition("completed", expected_attempt=...)`에 연결. 엔진과 CAS 표는 이미 준비되어 있다.
|
||||
3. Pending Notification 지연 알림·크래시 복구 (`state-transitions.md` §5).
|
||||
4. `preexec_fn`: Phase 2a는 데몬을 스폰하지 않아 미노출. 2b가 스폰을 도입하면 스레드 안전한 방식으로 교체해야 한다.
|
||||
5. **`started`의 세션 확인 (O-A)**: `_decide`의 `claim`/`started`는 아직 "작업 할당 세션 일치"를 검사하지 않는다(`pick_pending`은 세션 필터를 하지만 `publish_event`의 `started`는 누구나 보낼 수 있다). 2b에서 `expected_session`을 추가할 것.
|
||||
6. **`stop_session.sh`의 무조건 `cancelled` (O-B)**: 이미 `completed`인 job에 대해 이제 거부된다(레거시는 덮어썼다). 표상 의도된 동작이며, 운영자가 확정 상태를 바꾸려면 `registry.py status --set`(운영자 권한)을 쓴다. 릴리스 노트 기록 대상.
|
||||
Reference in new issue
Block a user