<!-- task=m-iop-agent-cli-runtime plan=9 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API -->

# Plan - Reject every semicolon in validation declaration prose

## 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 ninth review confirmed that the declared non-adjacent operator matrix and fresh safe regression suites pass, but the prose helper still accepts semicolons outside its selected word patterns. A fresh reviewer probe proved that ordinary prose containing `;` can erase the exact dispatcher command before caller scanning. This follow-up makes the stated operator invariant unconditional without changing product runtime behavior.

## Archive Evidence Snapshot

- `agent-task/m-iop-agent-cli-runtime/plan_cloud_G04_8.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G04_8.log`: ninth loop, FAIL with 1 Required, 0 Suggested, and 0 Nit findings.
- Remaining Required finding: `containsUnsafeValidationProse` rejects semicolons only for selected following words, selected preceding words, or an end-of-prose position, contrary to the active plan requirement to reject every semicolon anywhere outside the exact command span.
- Fresh reviewer evidence: the prescribed focused ownership suite, safe full `apps/agent/...` suite with only `TestBuiltBinaryHeadlessS10Transcript` skipped, and the race suite passed. A temporary reviewer test proved that `- Validate; please run \`<exact-command>\` now.` returns the command as a declaration and removes it from scanner text; the probe file was removed immediately. No product `iop-agent` binary or real provider CLI was executed.
- Roadmap carryover: `cli-surface` remains the only unchecked Milestone Task and requires SDD S10 headless evidence plus `Roadmap Completion` after the supporting 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 loop evidence fixed by the active pair: `agent-task/m-iop-agent-cli-runtime/plan_cloud_G04_7.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G04_7.log`.
- Changed test oracle, read in full: `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/PHASE.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 verification: `agent-ops/rules/project/rules.md`, `agent-ops/rules/project/domain/agent/rules.md`, `agent-ops/rules/project/domain/testing/rules.md`, `agent-ops/rules/common/rules-roadmap.md`, `agent-test/local/rules.md`, and `agent-test/local/testing-smoke.md`.
- Workflow: `agent-ops/skills/common/router.md`, `agent-ops/skills/common/code-review/SKILL.md`, `agent-ops/skills/common/plan/SKILL.md`, `agent-ops/skills/common/finalize-task-routing/SKILL.md`, and `agent-ops/skills/common/plan/templates/review-stub-template.md`.
- Agent spec: `agent-ops/rules/common/rules-agent-spec.md` and `agent-spec/index.md`; no standalone `iop-agent` CLI spec matches this work.

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`; status `[approved]`, lock released, and no unresolved `USER_REVIEW.md`.
- 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 declared Agent-Ops documents and exact command forms.
- The checklist retains accepted S10 evidence and makes the S13 shell-operator boundary unconditional, with deterministic direct and end-to-end semicolon fixtures, before emitting `cli-surface` Roadmap Completion.

### Verification Context

- Supplied handoff: ninth-review source inspection, active pair, 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 and unrelated provider-usage task changes.
- Fresh reviewer commands passed: the prescribed focused ownership tests, safe full Agent tests with only the prohibited compiled-binary test skipped, and the internal race suite.
- Fresh reviewer reproducer: a temporary test called `classifyExactValidationDocumentation` with `- Validate; please run \`<exact-command>\` now.`. It failed because the exact candidate was declared and removed from scanner text; the file was removed immediately after execution.
- Preconditions: retain the structural span parser, exact candidate/written identity accounting, compiled transcript, canonical slug behavior, 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 remains prior S14 evidence.
- Gap and confidence: the remaining gap is deterministic and isolated to unconditional semicolon validation in one test file; confidence is high.

### Test Coverage Gaps

- Existing negative cases cover semicolons adjacent to the exact span and the selected words `preface`, `check`, `then`, and `run`, but do not prove that arbitrary surrounding prose containing `;` fails closed.
- Add prefix and suffix cases whose words are absent from the helper's lists, and retain the complete accepted-form and other shell-metacharacter matrices.

### Symbol References

- No production symbol is renamed or removed.
- `containsUnsafeValidationProse` and the semicolon regex variables are test-local in `apps/agent/internal/taskloop/cutover_test.go`; `classifyExactValidationDocumentation` is their sole behavior consumer.

### Split Judgment

Keep one compact plan. Unconditional operator validation and its direct/end-to-end fixtures are one fail-closed ownership invariant in one test file.

### Scope Rationale

- Change only `apps/agent/internal/taskloop/cutover_test.go` and the active review evidence.
- Retain task-owned contract, compiled transcript, canonical slug, workflow, and adapter changes unchanged.
- 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=9`, `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_REVIEW_REVIEW_REVIEW_REVIEW_API-1] Reject every semicolon in parsed Markdown prose unconditionally and add arbitrary-word prefix/suffix regression cases.
- [ ] [REVIEW_REVIEW_REVIEW_REVIEW_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_REVIEW_REVIEW_REVIEW_REVIEW_API-1] Make semicolon rejection unconditional

**Problem**

`apps/agent/internal/taskloop/cutover_test.go:580-595` treats `;` differently from the other forbidden single-character shell metacharacters. The helper accepts a semicolon when its surrounding words are absent from two enumerated regexes, so documentation such as `- Validate; please run \`<exact-command>\` now.` erases the dispatcher call before ownership scanning despite the S13 exact-declaration rule.

**Solution**

- Include `;` in the unconditional `strings.ContainsAny` shell-metacharacter check.
- Remove `unsafeSemicolonCommandChain`, `unsafeSemicolonPrecedingWord`, and the conditional semicolon branch; do not replace them with another word list.
- Extend `TestCutoverProductionOwnershipRejectsNonExactValidationVariants` with arbitrary-word prefix and suffix semicolon cases. Keep its direct classifier assertion and exact path/line end-to-end assertion.
- Preserve accepted English prose punctuation other than the explicitly forbidden shell metacharacters and retain all existing accepted declaration forms.

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

```go
if strings.ContainsAny(prose, "><|&") {
	return true
}
if strings.Contains(prose, ";") {
	// Selected word-pattern checks.
}
```

After:

```go
if strings.ContainsAny(prose, ";><|&") {
	return true
}
```

**Modified Files and Checklist**

- [ ] `apps/agent/internal/taskloop/cutover_test.go`: reject all semicolons and add direct plus end-to-end arbitrary-word fixtures.

**Test Strategy**

- Add `non_adjacent_semicolon_unlisted_prefix` using `Validate; please run` and `non_adjacent_semicolon_unlisted_suffix` using `when ready; printf done`.
- Require both cases to return the original line with no declared identity and fail ownership validation at the exact injected path/line.
- Retain `TestClassifyExactValidationDocumentationAcceptsDeclaredForms` unchanged as the positive contract.

**Verification**

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

Expected: PASS; arbitrary-word semicolon prose and every other shell composition remain visible to caller scanning, while accepted declarations retain exact identities.

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

**Problem**

The final ownership guard controls whether retained S10 transcript and S13 cutover evidence can support `cli-surface` Roadmap Completion. Final verification must cover the current checkout without executing the product binary or a real provider CLI in the active task loop.

**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 any deviation 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.

**Test Strategy**

- Item 1 owns the regression matrix for the structural parser.
- Use `-count=1` and task-specific external caches. The safe full suite skips exactly `TestBuiltBinaryHeadlessS10Transcript`; no real provider CLI is allowed.
- Re-run the internal race suite because a PASS emits the final S10 roadmap evidence.

**Verification**

```bash
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-final/cache go test -count=1 -skip '^TestBuiltBinaryHeadlessS10Transcript$' ./apps/agent/...
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-final/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_REVIEW_REVIEW_REVIEW_REVIEW_API-1 |
| `agent-task/m-iop-agent-cli-runtime/CODE_REVIEW-cloud-G04.md` | REVIEW_REVIEW_REVIEW_REVIEW_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-final/cache /var/tmp/iop-cli-cutover-final/race-cache /var/tmp/iop-cli-cutover-final/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-final/cache go test -count=1 -v ./apps/agent/internal/taskloop -run '^(TestClassifyExactValidationDocumentationAcceptsDeclaredForms|TestCutoverProductionOwnershipHasNoReferenceCallerOrStaticRouteTable|TestCutoverProductionOwnershipRejectsInjectedPythonCaller|TestCutoverProductionOwnershipRejectsUnexpectedCallerInAllowedDocument|TestCutoverProductionOwnershipRejectsNonExactValidationVariants|TestCutoverProductionOwnershipRejectsMissingDeclaredValidationCommand)$'
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-final/cache go test -count=1 -skip '^TestBuiltBinaryHeadlessS10Transcript$' ./apps/agent/...
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-final/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 parser, 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-final/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-final/cache make build-agent
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-final/darwin-cache GOOS=darwin GOARCH=arm64 go build -trimpath -o /var/tmp/iop-cli-cutover-final/iop-agent-darwin-arm64 ./apps/agent/cmd/agent
TMPDIR=/var/tmp/i GOTMPDIR=/var/tmp/i GOCACHE=/var/tmp/iop-cli-cutover-final/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|TestClassifyExactValidationDocumentationAcceptsDeclaredForms|classifyExactValidationDocumentation|parseMarkdownCodeSpans|validationProse|containsUnsafeValidationProse|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: ownership references are intentional, prose validation is test-local and unconditional for shell metacharacters, 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`.
