<!-- task=m-iop-agent-cli-runtime plan=5 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API -->

# Plan - Fail-closed dispatcher validation document parsing

## For the Implementing Agent

Filling the implementation-owned sections in `CODE_REVIEW-*-G??.md` is mandatory. Implement the checklist, run every verification command, paste actual notes and stdout/stderr into the active review file, leave the active Plan/Review files in place, and report ready for review. Final verdicts, log renames, `complete.log`, and archive moves belong only to the code-review skill. If blocked, record only the exact blocker, attempted commands/output, and resume condition 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 fifth review proved that the new dispatcher validation exemption still accepts executable prefixes, shell composition, redirection, and positional suffixes outside the two covered examples. This follow-up replaces the open-ended wrapper/suffix heuristics with a fail-closed documentation-boundary parser and closes the complete observed variant set without changing product runtime behavior.

## Archive Evidence Snapshot

- `agent-task/m-iop-agent-cli-runtime/plan_local_G07_0.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G07_0.log`: first loop, FAIL with 2 Required findings.
- `agent-task/m-iop-agent-cli-runtime/plan_cloud_G06_1.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G07_1.log`: second loop, FAIL with 2 Required findings.
- `agent-task/m-iop-agent-cli-runtime/plan_cloud_G07_2.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G07_2.log`: third loop, FAIL with 2 Required findings.
- `agent-task/m-iop-agent-cli-runtime/plan_cloud_G08_3.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G08_3.log`: fourth loop, FAIL with 1 Required finding.
- `agent-task/m-iop-agent-cli-runtime/plan_cloud_G04_4.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G04_4.log`: fifth loop, FAIL with 1 Required, 0 Suggested, and 0 Nit findings.
- Remaining Required finding: `removeExactDeclaredValidationCommand` accepts `env <exact-command>`, `$(<exact-command>)`, `<exact-command> > /tmp/validation.out`, and `<exact-command> unexpected` because it removes the command before the caller scan.
- Fresh reviewer evidence: the prescribed focused tests, the safe full `apps/agent/...` suite with only `TestBuiltBinaryHeadlessS10Transcript` skipped, vet, current-host build, Darwin arm64 cross-build, logged-smoke preflight, and `git diff --check` passed. The reviewer did not execute the product `iop-agent` binary or a real provider CLI.
- Roadmap carryover: `cli-surface` remains the only unchecked Milestone Task and requires SDD S10 headless evidence plus `Roadmap Completion` after the exact S13 ownership guard passes.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`
- Milestone link: [Milestone document](agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md)
- Task ids:
  - `cli-surface`: headless binary, split config, Milestone discovery/selection/preview, lifecycle, and per-work overlay/integration/blocker observation
- Completion mode: check-on-pass

## Analysis

### Files Read

- Active loop: `agent-task/m-iop-agent-cli-runtime/PLAN-cloud-G04.md` and `agent-task/m-iop-agent-cli-runtime/CODE_REVIEW-cloud-G04.md`.
- Prior verdict evidence: `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G07_0.log`, `code_review_cloud_G07_1.log`, `code_review_cloud_G07_2.log`, and `code_review_cloud_G08_3.log`.
- Changed oracle: `apps/agent/internal/taskloop/cutover_test.go`.
- Contract and design: `agent-contract/index.md`, `agent-contract/inner/iop-agent-cli-runtime.md`, `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`, and `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`.
- Rules and workflow: `agent-ops/rules/project/rules.md`, `agent-ops/rules/project/domain/agent/rules.md`, `agent-ops/rules/project/domain/testing/rules.md`, `agent-test/local/rules.md`, `agent-test/local/testing-smoke.md`, `agent-ops/skills/common/code-review/SKILL.md`, `agent-ops/skills/common/plan/SKILL.md`, and `agent-ops/skills/common/finalize-task-routing/SKILL.md`.

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`; status `[approved]`, lock released, and no unresolved user review.
- Primary target: S10 / `cli-surface`; its Evidence Map requires binary plus split-config command integration and a headless operation transcript.
- Supporting boundary: S13 requires zero product Python fallback/callers while the transitional dispatcher validation preflight is restricted to the declared Agent-Ops documents and exact command forms.
- The checklist retains the accepted S10 transcript evidence and requires the S13 document parser to reject the complete reviewer-observed non-exact variant set before emitting `cli-surface` Roadmap Completion.

### Verification Context

- Supplied handoff: fifth-review source inspection, current active pair, prior verdict logs, current diff, claimed implementation output, and predicted archive identities.
- Local preflight: `/config/workspace/iop-s0`, Go `/config/.local/bin/go`, `go version go1.26.2 linux/arm64`, and `GOROOT=/config/opt/go`; the worktree contains task-owned carryover plus unrelated provider-usage task changes.
- Fresh reviewer commands passed: focused ownership tests, safe full Agent tests with only the prohibited compiled-binary test skipped, vet, build, Darwin arm64 cross-build, logged-smoke preflight, deterministic ownership search, and `git diff --check`.
- Fresh reviewer reproducer: one temporary table-driven test, removed after execution, showed four accepted non-exact callers: `env` prefix, command substitution, output redirection, and positional suffix.
- Preconditions: retain the restored compiled transcript, canonical slug behavior, exact adapter DTO, aligned S13 contract, and prior task-owned files. Use deterministic temporary fixtures and no real provider process.
- Constraints: do not edit Agent-Ops common/project rules or skills, production CLI/runtime behavior, roadmap, SDD, contract, or agent-spec. Official worker/review/final-verification paths must not execute the product `iop-agent` binary.
- External Verification Preflight: not applicable. Darwin is a local cross-build, and logged-in macOS/provider execution is prior S14 evidence.
- Gap and confidence: all observed bypass forms are deterministic in the current test-local parser; confidence is high.
- Agent spec: `agent-spec/index.md` has no matching standalone `iop-agent` CLI spec, so code, contract, SDD, and tests remain authoritative.

### Test Coverage Gaps

- Existing tests reject one `--dry-run` suffix and one `bash -c` wrapper but do not reject other executable prefixes, command substitution, redirection, quoted/positional suffixes, or multiple composed tokens.
- Positive coverage must continue to accept only the exact candidate-plan and written-plan documentation forms in the two declared documents.
- The repository ownership test covers current documents but cannot replace deterministic negative fixtures for parser boundaries.

### Symbol References

- `declaredDispatcherValidationCommand` is now unused and declared only in `apps/agent/internal/taskloop/cutover_test.go`; remove it.
- `removeExactDeclaredValidationCommand` is declared at `apps/agent/internal/taskloop/cutover_test.go:259` and called by `noDispatcherCallerViolation` in the same file. If renamed, update that sole call site and deterministic searches.
- No production symbol changes are allowed.

### Split Judgment

Keep one compact plan. Exact documentation recognition and caller rejection form one fail-closed scanner invariant in one test file; splitting the parser from its regression matrix would not create an independently acceptable state.

### Scope Rationale

- Change only `apps/agent/internal/taskloop/cutover_test.go` and the active review evidence.
- Retain the task-owned contract, compiled transcript, canonical slug, and workflow test changes in the write claim until final PASS, but do not edit them.
- Exclude product runtime behavior, Agent-Ops rules/skills, roadmap, SDD, agent-spec, real provider execution, and product-binary execution.

### Final Routing

- `evaluation_mode=isolated-reassessment`; finalizer `finalize-task-policy.sh`, mode `pair`.
- Build closures: scope/context/verification/evidence/ownership/decision all `true`; grade scores `1/0/1/1/1` = `G04`; base `local-fit`, final `recovery-boundary`, lane `cloud`.
- Review closures: scope/context/verification/evidence/ownership/decision all `true`; grade scores `1/0/1/1/1` = `G04`; route `official-review`, lane `cloud`, adapter `codex`, model `gpt-5.6-sol`, reasoning `xhigh`.
- `large_indivisible_context=false`; positive loop risks: `boundary_contract`, `structured_interpretation` (`loop_risk_count=2`).
- Recovery signals: `review_rework_count=5`, `evidence_integrity_failure=false`; recovery boundary matched.
- Capability gap: none.
- Canonical files: `PLAN-cloud-G04.md`, `CODE_REVIEW-cloud-G04.md`.

## Implementation Checklist

- [ ] [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1] Replace heuristic dispatcher exemption stripping with a fail-closed documentation-boundary parser and reject the full observed non-exact variant set.
- [ ] [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2] Run the fresh no-product-binary S10/S13 closure matrix and record exact output.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1] Fail-closed declared-command parsing

**Problem**

`apps/agent/internal/taskloop/cutover_test.go:259-295` tries to recognize an exact command by removing it unless small wrapper and suffix allowlists match. Any unlisted executable prefix or suffix loses the dispatcher token before the caller patterns run, so non-exact callers pass the S13 guard.

**Solution**

- Replace wrapper/operator enumeration with explicit allowed documentation shapes: exact inline-code spans and a whole line whose trimmed content equals exactly one declared candidate/written-plan command.
- Remove only those complete allowed shapes. Leave any prefix, suffix, shell composition, redirection, command substitution, repeated executable occurrence, or malformed code span untouched for the caller scan.
- Use the same exact classifier for the required candidate/written command presence check and remove the unused regular expression.

Before (`apps/agent/internal/taskloop/cutover_test.go:259`):

```go
idx := strings.Index(content, exactCmd)
if idx != -1 && !hasShellWrapperPrefix(prefix) && !hasExtraCommandSuffix(suffix) {
    content = content[:idx] + suffix
}
```

After:

```go
remaining, declared := stripExactValidationDocumentation(line)
if declared {
    declaredCounts[command]++
}
if dispatcherCallerPattern.MatchString(remaining) {
    return callerViolation(path, lineNumber)
}
```

The shape is illustrative; keep all matching logic test-local and fail closed.

**Modified Files and Checklist**

- [ ] `apps/agent/internal/taskloop/cutover_test.go`: replace heuristic stripping/presence checks, remove dead symbols, and add the complete table-driven negative matrix while retaining exact positive forms.

**Test Strategy**

- Add or extend a table-driven test to reject the known set together: `env` prefix, command substitution, output redirection, positional suffix, quoted flag suffix, shell operators, and multiple executable occurrences.
- Require exact document path and line evidence for every rejection.
- Retain the candidate-plan and written-plan positive forms and the dispatcher-owner whole-document exception.

**Verification**

```bash
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache go test -count=1 -v ./apps/agent/internal/taskloop -run '^(TestCutoverProductionOwnershipHasNoReferenceCallerOrStaticRouteTable|TestCutoverProductionOwnershipRejectsInjectedPythonCaller|TestCutoverProductionOwnershipRejectsUnexpectedCallerInAllowedDocument|TestCutoverProductionOwnershipRejectsNonExactValidationVariants)$'
```

Expected: PASS; every observed non-exact form fails with exact path/line evidence and only declared documentation shapes remain exempt.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2] Fresh safe S10/S13 closure

**Problem**

The remaining guard defect controls whether the retained S10 transcript and S13 cutover evidence can support final Roadmap Completion. Final verification must cover the current checkout without violating the active-task prohibition on product-binary execution.

**Solution**

- Run the focused parser matrix, safe full Agent suite, internal race matrix, static analysis, builds, and logged-smoke preflight with fresh external caches.
- Preserve prior compiled transcript evidence and do not execute a product binary or real provider CLI.
- Record every command's actual stdout/stderr and deviations in the active review file.

**Modified Files and Checklist**

- [ ] `agent-task/m-iop-agent-cli-runtime/CODE_REVIEW-cloud-G04.md`: fill implementation evidence and exact command output.
- [ ] Retain `agent-contract/inner/iop-agent-cli-runtime.md`, `apps/agent/cmd/agent/main_test.go`, `apps/agent/internal/taskloop/workflow.go`, and `apps/agent/internal/taskloop/workflow_test.go` unchanged as task-owned carryover.

**Test Strategy**

- Item 1 owns the new regression matrix.
- Use `-count=1` and temporary caches. The full safe suite skips exactly `TestBuiltBinaryHeadlessS10Transcript`; no real provider CLI is allowed.
- Re-run the internal race suite because this PASS would emit the final S10 roadmap evidence.

**Verification**

```bash
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache go test -count=1 -skip '^TestBuiltBinaryHeadlessS10Transcript$' ./apps/agent/...
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/race-cache go test -count=1 -race ./apps/agent/internal/taskloop ./apps/agent/internal/command ./apps/agent/internal/bootstrap ./packages/go/agenttask ./packages/go/agentstate
```

Expected: PASS across the safe Agent packages and internal race matrix without product-binary or real-provider execution.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/agent/internal/taskloop/cutover_test.go` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-1 |
| `agent-contract/inner/iop-agent-cli-runtime.md` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2 ownership carryover; no planned edit |
| `apps/agent/cmd/agent/main_test.go` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2 ownership carryover; no planned edit |
| `apps/agent/internal/taskloop/workflow.go` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2 ownership carryover; no planned edit |
| `apps/agent/internal/taskloop/workflow_test.go` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2 ownership carryover; no planned edit |
| `agent-task/m-iop-agent-cli-runtime/CODE_REVIEW-cloud-G04.md` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API-2 |

## Final Verification

Fresh execution is required; cached Go test output is not acceptable. Do not execute the product `iop-agent` binary or a real provider CLI.

```bash
install -d -m 700 /var/tmp/i /var/tmp/iop-cli-cutover-next/cache /var/tmp/iop-cli-cutover-next/race-cache /var/tmp/iop-cli-cutover-next/darwin-cache
gofmt -w apps/agent/internal/taskloop/cutover_test.go
```

Expected: temporary directories are ready outside the repository and formatting completes without error.

```bash
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache go test -count=1 -v ./apps/agent/internal/taskloop -run '^(TestCutoverProductionOwnershipHasNoReferenceCallerOrStaticRouteTable|TestCutoverProductionOwnershipRejectsInjectedPythonCaller|TestCutoverProductionOwnershipRejectsUnexpectedCallerInAllowedDocument|TestCutoverProductionOwnershipRejectsNonExactValidationVariants)$'
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache go test -count=1 -skip '^TestBuiltBinaryHeadlessS10Transcript$' ./apps/agent/...
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/race-cache go test -count=1 -race ./apps/agent/internal/taskloop ./apps/agent/internal/command ./apps/agent/internal/bootstrap ./packages/go/agenttask ./packages/go/agentstate
```

Expected: focused, safe full Agent, and internal race suites PASS without executing the product binary.

```bash
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache go vet ./apps/agent/internal/taskloop ./apps/agent/cmd/agent ./apps/agent/internal/bootstrap ./packages/go/...
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache make build-agent
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/darwin-cache GOOS=darwin GOARCH=arm64 go build -trimpath -o /var/tmp/iop-cli-cutover-next/iop-agent-darwin-arm64 ./apps/agent/cmd/agent
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-next/cache make test-iop-agent-logged-smoke-preflight
```

Expected: vet, current-host build, Darwin arm64 cross-build, and non-provider logged-smoke preflight PASS.

```bash
rg --sort path -n '\b(TestCutoverProductionOwnership|stripExactValidationDocumentation|removeExactDeclaredValidationCommand|declaredDispatcherValidationCommand|dispatch\.py)\b' apps/agent/internal/taskloop/cutover_test.go agent-contract/inner/iop-agent-cli-runtime.md agent-ops/skills/common/plan/SKILL.md agent-ops/skills/common/code-review/SKILL.md agent-ops/skills/project/orchestrate-agent-task-loop/SKILL.md
git diff --check
git status --short
```

Expected: exact ownership references are intentional, obsolete heuristic/dead symbols are absent, no whitespace errors exist, and only task-owned changes plus unrelated pre-existing worktree changes remain.

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