[verified] Allow rework from a single valid review request
This commit is contained in:
@@ -79,7 +79,7 @@ Repository file을 수정하기 전에 다음을 모두 검증한다.
|
||||
- Changed-file, review, review-comment와 commit pagination이 완전하고 diff가 truncated·ambiguous하지 않다.
|
||||
- Canonical Issue worktree와 PR head branch를 현재 실행이 안전하게 재사용할 수 있다.
|
||||
|
||||
Canonical input-gate의 `decision.rework_review_ids`는 현재 head·계약에 결합된 role별 최신 `REQUEST_CHANGES`만 포함한다. `rework`에서도 finding의 계약 근거·scope·독립 승인과 lease/worktree 조건을 별도로 확인한 뒤에만 수정한다. `COMMENT`는 자동 actionable 판정을 하지 않고 `blocked`로 남겨 main의 수동 분류 또는 별도 승인 절차로 넘긴다. 특히 `blocked_spec`, 계약 모순, 선택되지 않은 설계 선택 또는 source reality와 계약 충돌은 구현 재작업으로 해결하지 않으며 Discovery 재검토가 필요하다고 보고한다. `blocked` receipt로 source를 수정하거나 no-op을 주장하지 않는다. Current head·계약의 spec와 code-review role별 최신 유효 review가 모두 `APPROVED`인 fresh `no_op` receipt에서만 write 없는 종료를 한다. 다른 role의 승인·old-head/stale/dismissed review·본문의 해결 주장은 이 조건을 대체하지 않는다.
|
||||
Canonical input-gate의 `decision.rework_review_ids`는 현재 head·계약에 결합된 role별 최신 `REQUEST_CHANGES`만 포함한다. Spec 또는 code-review role 중 하나 이상에 유효한 최신 수정 요청이 있고 다른 차단 사유가 없으면 `rework`다. 다른 role의 유효 review 부재는 `missing_current_review`로 기록하되 이 수정 요청의 재작업 착수를 차단하지 않는다. 수정 요청 없이 review가 부족하면 `blocked`이며 no-op으로 종료하지 않는다. `rework`에서도 finding의 계약 근거·scope·독립 승인과 lease/worktree 조건을 별도로 확인한 뒤에만 수정한다. `COMMENT`는 자동 actionable 판정을 하지 않고 `blocked`로 남겨 main의 수동 분류 또는 별도 승인 절차로 넘긴다. 특히 `blocked_spec`, 계약 모순, 선택되지 않은 설계 선택 또는 source reality와 계약 충돌은 구현 재작업으로 해결하지 않으며 Discovery 재검토가 필요하다고 보고한다. `blocked` receipt로 source를 수정하거나 no-op을 주장하지 않는다. Current head·계약의 spec와 code-review role별 최신 유효 review가 모두 `APPROVED`인 fresh `no_op` receipt에서만 write 없는 종료를 한다. 다른 role의 승인·old-head/stale/dismissed review·본문의 해결 주장은 이 조건을 대체하지 않는다.
|
||||
|
||||
## Snapshot과 finding matrix
|
||||
|
||||
|
||||
@@ -42,8 +42,8 @@ The `gitea-agent.rework-input-gate/v1` receipt retains parsed native records, pr
|
||||
|
||||
Order by UTC instant with exact up-to-nine-digit fractional precision, then numeric review ID for deterministic display ties. ID order is not causal attestation. Conflicting same-instant same-role state/body/marker records block and have no selected review. Markers use the actual canonical code FIRST-line and spec LAST-line formats; spec result digest and correlation match its renderer's separator-LF algorithm. Current authoritative marker/head/contract/state contradictions block. Role IDs must be positive, distinct from impl, and consistent; unrelated roles cannot supply required approvals. Old-head history is recorded but cannot determine current-head action.
|
||||
|
||||
- `rework`: both roles have a current usable selection, and the only remaining decision reason is latest role-specific `REQUEST_CHANGES`. `decision.rework_review_ids` contains those request IDs only, never spec/code approvals. Validate their findings and authorization independently before source edits.
|
||||
- `rework`: at least one role has a current usable latest `REQUEST_CHANGES`, and there are no blocking reasons other than review absence. A missing counterpart is retained as `missing_current_review` information and does not block acting on the valid request. `decision.rework_review_ids` contains only selected current request IDs, never absent roles, excluded history or spec/code approvals. Validate their findings and authorization independently before source edits.
|
||||
- `no_op`: both spec and code-review role-specific latest current-head, nonstale, nondismissed reviews are `APPROVED` for the fresh contract. A spec approval cannot supersede a code request. Earlier same-role requests may be superseded by a later valid same-role approval, never by another role.
|
||||
- `blocked`: missing current roles, pending authoritative reviews, malformed/ambiguous bindings, same-instant conflicts, current manual `COMMENT`, or `blocked_spec` prevent automatic action. `blocked_spec` is explicit and routes to Discovery investigation, not impl repair. No keyword heuristic or marker alone proves actionable finding semantics.
|
||||
- `blocked`: missing current roles without a usable latest request, pending authoritative reviews, malformed/ambiguous bindings, same-instant conflicts, current manual `COMMENT`, or `blocked_spec` prevent automatic action. Actual blocking reasons take precedence even when a valid request exists. `blocked_spec` is explicit and routes to Discovery investigation, not impl repair. No keyword heuristic or marker alone proves actionable finding semantics.
|
||||
|
||||
This gate's no-op means skip implementation rework, not native review publisher idempotent reuse (which can reuse an existing REQUEST_CHANGES review). Publication, journals and their candidate-selection rules remain unchanged. A receipt is neither publication success nor edit permission, lease/worktree admission, full Discovery approval, independent reviewer-ID attestation, or causal event proof. Do not reuse an old receipt as authority; recheck provider/head/contract and independent upstream gates before an action.
|
||||
|
||||
@@ -210,11 +210,17 @@ def derive_decision(raw, inp, impl_actor_id):
|
||||
latest=same[-1]; selected[role]=latest['id']
|
||||
if latest['_verdict']=='request_changes': reasons.append('request_changes')
|
||||
elif latest['_verdict']=='blocked_spec': reasons.append('blocked_spec')
|
||||
if not reasons:
|
||||
status='no_op'
|
||||
elif reasons and set(reasons) == {'request_changes'}:
|
||||
status='rework'
|
||||
else: status='blocked'
|
||||
reason_set = set(reasons)
|
||||
# Missing peer review prevents no-op, not acting on a valid selected request.
|
||||
blocking_reasons = reason_set - {'request_changes', 'missing_current_review'}
|
||||
if blocking_reasons:
|
||||
status = 'blocked'
|
||||
elif 'request_changes' in reason_set:
|
||||
status = 'rework'
|
||||
elif 'missing_current_review' in reason_set:
|
||||
status = 'blocked'
|
||||
else:
|
||||
status = 'no_op'
|
||||
for row in timeline:
|
||||
for key in ('_time','_verdict','_role','_marker_error'): row.pop(key,None)
|
||||
decision={'status':status,'reason_codes':sorted(set(reasons)),'target':copy.deepcopy(inp['target']),'head':inp['head'],
|
||||
|
||||
Reference in New Issue
Block a user