<!-- task=agent_task_english_contract plan=2 tag=REVIEW_REFACTOR -->

# Close the Verdict Schema and Completion-Scan Contracts

## For the Implementing Agent

Filling implementation-owned sections in `CODE_REVIEW-*-G??.md` is the mandatory final implementation step. Run every verification command, record actual notes and stdout/stderr, keep the active files in place, and report ready for review. Finalization belongs only to the code-review skill. If blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence fields; do not ask the user, call user-input tools, create control-plane stop files, classify the next state, archive logs, or write `complete.log`.

## Background

The second review confirmed that restart execution and identity-matching recovery were repaired, and every fresh test command passed. It also found that the verdict parser accepts undocumented mixed-language schemas, the completion-scan regression still depends on a timing sleep, and the artifact-language assertions cover only part of the promised contract. This follow-up closes only those three Required findings.

## Archive Evidence Snapshot

- Prior plan: `agent-task/agent_task_english_contract/plan_cloud_G07_1.log`
- Prior review: `agent-task/agent_task_english_contract/code_review_cloud_G07_1.log`
- Verdict: `FAIL`
- Required findings: pair each canonical or legacy verdict heading with only its matching label; replace the convergence test's completion-scan timing sleep with an observation barrier; cover the complete canonical-label, explicit legacy-alias, verdict-finalization, and prompt-language contract.
- Suggested findings: none.
- Nit findings: none.
- Affected files: `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py` and `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`.
- Verification evidence: reviewer `py_compile`, five language-contract tests, seven focused tests, the fresh 267-test suite, and `git diff --check` passed. A direct parser probe still returned `PASS` for canonical heading plus Korean label and `WARN` for Korean heading plus canonical label, proving the uncovered contract defect.
- Roadmap carryover: none. This task is not Milestone-linked and has no `Roadmap Targets`.
- Implementation rule: use this snapshot and the two named logs as prior-loop evidence; do not search `agent-task/archive/**`.

## Analysis

### Files Read

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/common/philosophy.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/finalize-task-routing/SKILL.md`
- `agent-ops/skills/common/plan/templates/review-stub-template.md`
- `agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md`
- `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`
- `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`
- `agent-test/local/rules.md`
- `agent-test/local/testing-smoke.md`
- `agent-spec/index.md`
- `agent-contract/index.md`
- `agent-task/agent_task_english_contract/plan_local_G06_0.log`
- `agent-task/agent_task_english_contract/code_review_cloud_G06_0.log`
- `agent-task/agent_task_english_contract/plan_cloud_G07_1.log`
- `agent-task/agent_task_english_contract/code_review_cloud_G07_1.log`

### SDD Criteria

Not applicable. This is non-roadmap Agent-Ops artifact-contract maintenance.

### Test Environment Rules

- `test_env=local`.
- `agent-test/local/rules.md` and `agent-test/local/testing-smoke.md` were present and read.
- Edge/Node smoke, live-provider, Docker, and external-runner profiles do not apply to an isolated Python parser and deterministic unittest-fixture change.
- Applied verification is fresh Python compilation, focused unittest cases, complete dispatcher unittest discovery, and `git diff --check`.
- Provider invocation and provider command construction remain denied by the existing test guards.
- No verification leaves the checkout, so no non-local preflight is required.

### Test Coverage Gaps

- `ArtifactLanguageContractTest` covers the two valid verdict pairs and duplicate headings, but it does not reject the two mixed heading/label directions or exercise both inline and block verdict forms as a schema matrix.
- The language-contract test checks eight template headings and one worker prompt, but it does not read the plan/code-review/orchestrator skills or exercise self-check, review, recovery, and continuation prompts.
- `DispatcherConvergenceSimulationTest.test_parallel_multi_task_followup_dependency_and_terminal_completion` asserts that a completion-triggered scan excludes running tasks, but alpha waits on `asyncio.sleep(0.005)` instead of the scan observation itself.

### Symbol References

No public function is renamed or removed. Keep `verdict_from_text`, `read_verdict`, `latest_verdict_log`, `matching_plan_log`, `base_prompt`, `logical_context_prompt`, `continuation_prompt_from_package`, and `continuation_prompt` stable. The verdict heading/label constants may be consolidated internally if every call site and test remains compatible.

### Split Judgment

Keep one plan. The parser and its artifact-language regression matrix are one compatibility boundary, while the small concurrency-fixture repair shares the same dispatcher test file and full-suite verification. Splitting would create overlapping writes to `test_dispatch.py` without independent archive or PASS value.

### Scope Rationale

- Modify only `dispatch.py` and `test_dispatch.py`.
- Treat the current plan skill, code-review skill, review template, and orchestrator skill as contract inputs for assertions; do not modify central common rules or skills.
- Do not change scheduler production behavior, recovery identity logic, restart behavior, roadmap state, agent-spec, agent-contract, runtime banners, `USER_REVIEW.md`, `complete.log`, or Korean user-facing final responses.
- Preserve unrelated user changes and all provider-deny seams.

### Final Routing

- `evaluation_mode=isolated-reassessment`
- `finalizer=finalize-task-policy.sh`, `finalizer_mode=pair`
- Build closures: scope/context/verification/evidence/ownership/decision are all `true`.
- Build grade scores: scope=2, state=2, blast=1, evidence=1, verification=1, total=`G07`.
- Build base/final route: `local-fit` -> `recovery-boundary`, lane=`cloud`, filename=`PLAN-cloud-G07.md`.
- Review closures: scope/context/verification/evidence/ownership/decision are all `true`.
- Review grade scores: scope=2, state=2, blast=1, evidence=1, verification=1, total=`G07`.
- Review route: `official-review`, lane=`cloud`, Codex `gpt-5.6-sol` xhigh, filename=`CODE_REVIEW-cloud-G07.md`.
- `large_indivisible_context=false`.
- Positive loop risks: `temporal_state`, `concurrent_consistency`, `boundary_contract`, `structured_interpretation`, `variant_product`; count=5.
- `review_rework_count=2`, `evidence_integrity_failure=false`.
- `risk_boundary_matched=true`, `recovery_boundary_matched=true`.
- Capability gap: none.

## Implementation Checklist

- [ ] [REVIEW_REFACTOR-1] Enforce paired canonical/legacy verdict schemas and complete the deterministic artifact-language contract matrix.
- [ ] [REVIEW_REFACTOR-2] Replace the completion-scan timing sleep with an explicit scan-observation barrier.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REFACTOR-1] Paired verdict schemas and complete language-contract coverage

#### Problem

`agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py:64-75,4346-4357` matches headings and verdict labels independently. This cross-product accepts canonical `Code Review Result` with Korean `종합 판정` and legacy `코드리뷰 결과` with English `Overall Verdict`, although `orchestrate-agent-task-loop/SKILL.md:153` documents only the two paired schemas. The declared heading and label tuples are not used by the parser. `test_dispatch.py:10155-10179` also verifies only eight template headings and one worker prompt, leaving the promised skill, finalization, alias, and prompt paths unguarded.

Before:

```python
# dispatch.py:64-75
CODE_REVIEW_RESULT_HEADINGS = ("Code Review Result", "코드리뷰 결과")
OVERALL_VERDICT_LABELS = ("Overall Verdict", "종합 판정")

VERDICT_HEADING_RE = re.compile(
    r"^##\s*(?:Code Review Result|코드리뷰 결과)[ \t]*$", re.MULTILINE
)
VERDICT_LINE_RE = re.compile(
    r"^(?:-\s*)?(?:\*\*)?(?:Overall Verdict|종합 판정)(?:\*\*)?\s*:\s*(PASS|WARN|FAIL)[ \t]*$",
    re.MULTILINE,
)
```

#### Solution

- Represent the canonical and legacy verdict contracts as explicit `(heading, label)` pairs.
- Select exactly one schema section, reject duplicate canonical/legacy headings, and match only that schema's label in both inline and `###` block forms.
- Use or remove the obsolete independent alias constants so the implementation has one source of truth.
- Extend `ArtifactLanguageContractTest` with a table covering both valid pairs and both mixed pairs for inline and block forms; mixed pairs must return `None`.
- Read the current plan skill, code-review skill, review template, and orchestrator skill from the test fixture. Assert every canonical artifact label named by the archived finding, exact explicit legacy-alias pairings, canonical `Code Review Result` finalization, and the documented canonical/legacy verdict pair.
- Exercise worker, Pi worker, self-check, official-review, review-recovery, logical-context, native continuation, and ordinary continuation prompt outputs. Every artifact-writing path must include `Keep artifact content in English.` and every child final-response path must include `Final in Korean.` as applicable.
- Keep Korean roadmap, `USER_REVIEW.md`, runtime banner, and user-facing response literals outside blanket language assertions.

After design:

```python
CODE_REVIEW_RESULT_SCHEMAS = (
    ("Code Review Result", "Overall Verdict"),
    ("코드리뷰 결과", "종합 판정"),
)

# Find exactly one schema heading, slice only that section, and compile
# line/block matchers from only the paired label with re.escape(label).
```

#### Modified Files and Checklist

- [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py`: make verdict heading/label selection schema-paired and fail closed on mixed or duplicate schemas.
- [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: add the inline/block valid-and-mixed verdict matrix.
- [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: assert the complete canonical label, explicit legacy alias, finalization, and prompt contract without modifying the contract source files.
- [ ] Preserve existing accepted canonical/legacy logs, identity matching, and public parser/prompt function names.

#### Test Strategy

Write regression coverage in `ArtifactLanguageContractTest`:

- `test_verdict_schema_pairs_reject_mixed_heading_labels`: use table-driven canonical/legacy headings, canonical/legacy labels, and inline/block fixtures; accept only matching-language pairs.
- Expand `test_templates_and_prompts_separate_artifact_and_final_languages`: read the four contract documents, enumerate the required canonical labels and explicit legacy aliases, and exercise every prompt constructor listed above with temporary task/context fixtures.
- Keep existing canonical, legacy, duplicate-heading, recovery identity, and mismatch tests unchanged unless refactoring them into the same complete matrix preserves all assertions.

#### Verification

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py ArtifactLanguageContractTest
```

Expected: all artifact-language tests pass, mixed verdict schemas fail closed, and no provider command is constructed or invoked.

### [REVIEW_REFACTOR-2] Completion-triggered scan observation barrier

#### Problem

`agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py:6476-6501` sets `beta_review_finished`, then keeps alpha active with `asyncio.sleep(0.005)`. The assertion is intended to prove that the dispatcher scans after beta completion with alpha in `exclude_names`, but the fixture does not wait for that scan and can race under scheduler load.

Before:

```python
# test_dispatch.py:6476-6487
alpha_in_review = asyncio.Event()
beta_review_finished = asyncio.Event()

if task.name == "sim/01_alpha" and attempt == 1:
    alpha_in_review.set()
    await beta_review_finished.wait()
    await asyncio.sleep(0.005)
```

#### Solution

- Add a `completion_scan_observed` event beside the existing review events.
- Wrap the real `dispatch.scan_tasks` with a synchronous observer that calls the original function and sets the event only when beta has finished and `exclude_names` contains the still-running alpha task.
- Make alpha await `completion_scan_observed.wait()` after `beta_review_finished.wait()` and remove the timing sleep from this ordering path.
- Keep the existing call-list assertion and archive/count assertions so the barrier strengthens rather than replaces behavioral coverage.
- Do not modify production scheduler logic or unrelated short sleeps used only to create parallel worker/self-check overlap.

After design:

```python
completion_scan_observed = asyncio.Event()

def observed_scan_tasks(*args, **kwargs):
    scanned = original_scan_tasks(*args, **kwargs)
    if (
        beta_review_finished.is_set()
        and "sim/01_alpha" in set(kwargs.get("exclude_names") or ())
    ):
        completion_scan_observed.set()
    return scanned

# Alpha remains active until the dispatcher itself performs the target scan.
await beta_review_finished.wait()
await completion_scan_observed.wait()
```

#### Modified Files and Checklist

- [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: add the scan-observation event and wrapped real scanner.
- [ ] `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py`: remove the completion-scan timing sleep and block alpha on the observed scan.
- [ ] Retain provider-deny behavior, timeout protection, concurrency overlap assertions, scan-call bounds, archive checks, and work-log assertions.

#### Test Strategy

Update `DispatcherConvergenceSimulationTest.test_parallel_multi_task_followup_dependency_and_terminal_completion`. The fixture must deterministically prove that a completion-triggered real scan occurs after beta finishes while alpha remains active and is excluded. No production code change is planned.

#### Verification

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py DispatcherConvergenceSimulationTest.test_parallel_multi_task_followup_dependency_and_terminal_completion
```

Expected: one test passes without timeout, and the scan-observation barrier—not elapsed time—releases alpha.

## Modified Files Summary

| File | Item |
|---|---|
| `agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py` | REVIEW_REFACTOR-1 |
| `agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py` | REVIEW_REFACTOR-1, REVIEW_REFACTOR-2 |

## Final Verification

```bash
python3 -m py_compile agent-ops/skills/project/orchestrate-agent-task-loop/scripts/dispatch.py
```

Expected: exit code 0 with no stdout/stderr.

```bash
python3 agent-ops/skills/project/orchestrate-agent-task-loop/tests/test_dispatch.py \
  ArtifactLanguageContractTest \
  DispatcherConvergenceSimulationTest.test_parallel_multi_task_followup_dependency_and_terminal_completion
```

Expected: every selected test passes; mixed schemas are rejected, the scan barrier completes, and no provider command is constructed or invoked.

```bash
python3 -m unittest discover -s agent-ops/skills/project/orchestrate-agent-task-loop/tests -p 'test_*.py'
```

Expected: every discovered dispatcher test passes in a fresh run with no real provider process.

```bash
git diff --check
```

Expected: exit code 0.

After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
