Issue #34: the loop waits for the creator job's sub-jobs, reviewers get the sub-job table as evidence, a run with sub-jobs voids a round whose source changed during review, and a pane caller reaches an agent of another workspace on its own server. VERSIONS.md carries the entry; the merge-side reports (round 1 @ed293dc and round 2 @e80186f with identity sidecars, baseed293dc-> heade80186f, evidence review-tree) are archived under .agents/reports/<session>/. Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01VCgu9Fa9iT7TbJUSzdq4Ff
6.8 KiB
PR #38 델타 리뷰 2회차 — bc07e3f0
PASS. 이전 리뷰의 차단 지적 R1/N1 및 R2가 해소됐다. K1 안내문 보완도 확인했으며, 이번 델타에서 새로운 병합 차단 결함을 발견하지 못했다.
대상 및 범위
- base:
ed293dcef4c346e0050a31cb46812bcdcf1d67cf - head:
e80186f56064eaf93a2f32c48d31d84816894774 - tree:
3501868872d828894f031911b8ca31b01ce77a72 - 검증 경로:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/mam-review/loop-20260925T072328Z-2f5853/1 git diff ed293dc...HEAD: registry.py, runner.py, test_issue34_job_tree.py 세 파일, +73/-10.- 검증 전후 HEAD/tree 일치 및 빈 git status 확인. 소스/제품 파일 수정, 커밋, 실제 herdr 세션 조작은 하지 않았다. 임시 사본과 격리된 registry/audit 자료만 사용했다.
- 이번에는 델타 및 직접 영향 범위를 검증했다. 이전 회차의 광범위한 287개 항목을 현재 HEAD에서 전부 재실행했다고 주장하지 않는다. 예정된 4.7.4 버전 bump 부재는 판정에서 제외했다.
지적별 재판정
R1/N1 — 취소 사유 누락: 해소
.agents/skills/lib_py/delegation/registry.py:316의 get_feedback(..., events=...) 기본값은 기존 completed/error로 유지된다. audit의 source_event/event와 로컬 events.log 모두 지정한 이벤트 집합을 사용한다. .agents/skills/lib_py/loop/runner.py:690의 하위 잡 조회만 cancelled를 추가한다.
실제 래퍼·등록부·발행기를 사용하는 T13 두 사례가 통과했다. 별도 탐침에서도 다음을 확인했다.
- cancelled + session_busy → NOT-DISPATCHED / session_busy
- cancelled + target_not_found → NOT-DISPATCHED / target_not_found
- cancelled + rolled back by create_session → NOT-DISPATCHED / 원래 사유
감사 로그 event 형식, 감사 로그 source_event 형식, 감사 로그가 없는 .events.log 폴백을 각각 분리해 검사했다. 이전 error 다음에 cancelled가 있는 자료에서 기본 API와 get-feedback CLI는 이전 error detail을 유지하고, 명시적으로 cancelled를 포함한 호출만 취소 detail을 읽었다. 래퍼의 기존 get-feedback CLI 호출에도 기본 동작 변경이 없다.
R2 — 원격 deadline 사유 오분류: 해소
.agents/skills/lib_py/loop/runner.py:695의 첫 단어 판정이 실제 deadline_timeout (remote runner)를 CLOSED-UNCONFIRMED로 분류한다. T14가 통과했으며, 별도로 실제 remote.handle_dispatch(..., exec_cmd=None)에 timeout_sec=1을 주어 마감을 발생시켰다.
이 탐침은 임시 registry/audit와 127.0.0.1:9 브로커를 사용했다. heartbeat 타이머 생성만 생략하고 실제 started/error 발행 및 로컬 기록 경로를 사용했다. 결과는 다음과 같다.
remote runner rc: 2
record: error
reason: deadline_timeout (remote runner)
classification: CLOSED-UNCONFIRMED
review table: 미확인 종결 1
warning: its agent may still be writing
브로커 연결 거절은 의도한 격리 조건이며, 로컬 기록과 분류는 정상 검증됐다.
deadline_timeout, agent_blocked 및 설명이 붙은 사유는 미확인 종결로 분류된다. session_busy, target_not_found, simulated, deadline_timeout_recovered 같은 다른 error 사유는 일반 error로 남는다. completed는 사유가 deadline_timeout이어도 completed이고, running은 OPEN이다. 따라서 부분 문자열 포함만으로 무관한 사유를 마감으로 분류하는 변경은 아니다.
K1 — 귀속 불명 잡 판정 안내: 해소
.agents/skills/lib_py/loop/runner.py:41의 STRAY_RULE 및 :726의 조건부 추가를 확인했다. T6와 별도 프롬프트 탐침에서 다음이 성립했다.
- 자손과 귀속 불명 열린 잡이 모두 없으면 추가 블록은 빈 문자열이다.
- 완료된 연결 자손만 있을 때 STRAY_RULE은 붙지 않는다.
- 귀속 불명 열린 잡이 있으면 STRAY_RULE이 정확히 한 번 붙는다.
- 그 잡이 종결되면 STRAY_RULE은 사라진다.
안내는 해당 잡의 산출물이 작업 목표에 필요한 경우 NOT PASS를 요구한다. 모든 무관한 잡을 자동으로 실패로 간주하지 않으며, 연결된 자손에 대한 SUBJOB_RULE과 모순되지 않는다.
검증 결과
브리프의 Python 및 검증 경로를 사용했다. 모든 pytest 실행은 AGENT_PYTHON_BIN=<main venv Python> PYTHONDONTWRITEBYTECODE=1 python -m pytest -q -p no:cacheprovider --basetemp=<검증 경로 밖 임시 경로> 형태였다.
| 검증 | 결과 |
|---|---|
| test_issue34_job_tree.py 전체 20개 + registry CLI 계약·shim help·패키지 import 경계 3개 | 23 passed / 84.42s |
| audit event / audit source_event / .events.log 폴백별 상태 분류 14개 | 42개 분류 단언 통과 |
| 위 세 저장 형식별 기본 API·확장 API·기본 CLI | 9개 호환성 단언 통과 |
| 실제 원격 마감 producer → feedback → 분류/표/경고 | 통과 |
| 빈 프롬프트 및 STRAY_RULE 조건부 노출 | 통과 |
| 변경 Python AST 구문 검사, git diff --check | 통과 |
선택한 기존 계약 테스트:
test_registry_cli_contract_snapshottest_shim_help_output_matches_pre_move_capturetest_delegation_package_imports_no_sibling_lib_py_modules
역검증
임시 skills 사본에서 registry.py와 runner.py만 ed293dc 버전으로 되돌렸다. 현행 테스트를 그 사본에 연결하면 다음 동작 단언들이 각각 실패했다.
| 사례 | 실패 근거 |
|---|---|
| T13[target_not_found] | test_issue34_job_tree.py:251 — cancelled / - 이므로 NOT-DISPATCHED + 사유 단언 실패 |
| T13[session_busy] | 같은 줄 — 동일한 취소 사유 누락 |
| T14 | :270 — 원격 마감이 error로 남아 CLOSED-UNCONFIRMED 단언 실패 |
| T6 | :509 — STRAY_RULE 문장 부재 |
최초 역검증 pytest 결과는 4 failed, 16 deselected, 1 teardown error / 9.82s였다. 추가 teardown 오류는 임시 사본의 non-delegation 모듈을 불러온 것을 기존 provenance guard가 검출한 것으로, 위 네 동작 실패와 별개다. 이를 구분하기 위해 동일한 네 테스트 함수를 독립 Python 프로세스에서 각 임시 경로와 MonkeyPatch context로 직접 실행했다. 네 경우 모두 정확히 위 동작 단언 줄에서 실패했고 다른 오류 없이 역검증을 마쳤다. 현행 HEAD의 대응 네 테스트는 앞선 정상 pytest 실행에서 모두 통과했다.
보조 자료:
- 저장 형식/분류 탐침:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/bc07e3f0-probes-1m01abus/ - 원격 producer/프롬프트 탐침:
/var/folders/q_/68sxgw3j073dgjg8wl9s08vw0000gn/T/bc07e3f0-integration-siocsre6/ - 정정 전 skills 사본:
/tmp/bc07e3f0-reverse.0e3SXO/skills/
이전 R1/R2에 따른 NOT PASS를 현재 리뷰 대상 e80186f에서는 철회한다. 추가 재계획 요청은 없다.
[VERDICT: PASS]