<!-- task=m-iop-agent-cli-runtime plan=7 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_API -->

# Plan - Make Markdown validation declarations structurally fail closed

## 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 seventh review confirmed that the previous backtick and repeated-occurrence regressions pass, but the Markdown classifier still erases dispatcher calls from additional non-declaration shapes. Inline declarations followed by shell composition and double-backtick spans bypass the S13 ownership guard, while the required deterministic positive fixture for accepted identities is still absent. This follow-up replaces outside-text heuristics with a structural Markdown declaration parser without changing product runtime behavior.

## Archive Evidence Snapshot

- `agent-task/m-iop-agent-cli-runtime/plan_cloud_G04_6.log` and `agent-task/m-iop-agent-cli-runtime/code_review_cloud_G04_6.log`: seventh loop, FAIL with 1 Required, 0 Suggested, and 0 Nit findings.
- Remaining Required finding: `classifyExactValidationDocumentation` accepts an exact inline declaration followed by `; echo done`, followed by `$(echo done)`, and wrapped in a double-backtick span; the planned positive fixture for accepted standalone and Markdown-inline candidate/written identities is absent.
- Fresh reviewer evidence: the prescribed focused suite, safe full `apps/agent/...` suite with only `TestBuiltBinaryHeadlessS10Transcript` skipped, race suite, vet, current-host build, Darwin arm64 cross-build, logged-smoke preflight, formatting check, deterministic ownership search, and `git diff --check` passed. A focused temporary reviewer probe failed all three new boundary cases and was removed after execution. 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 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_G04_5.log`.
- Changed test 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/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 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`.
- 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 preserves accepted S10 evidence and requires a structural exact Markdown parser, exact identity accounting, and deterministic positive/negative classifier fixtures before emitting `cli-surface` Roadmap Completion.

### Verification Context

- Supplied handoff: seventh-review source inspection, active pair, prior verdict evidence, 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, the internal race suite, vet, current-host build, Darwin arm64 cross-build, logged-smoke preflight, deterministic ownership search, formatting check, and `git diff --check`.
- Fresh reviewer reproducer: a temporary three-case test proved that semicolon composition, suffix command substitution, and double-backtick wrapping return no ownership violation; the temporary file was removed immediately after execution.
- 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 remains prior S14 evidence.
- Gap and confidence: the remaining gap is deterministic and isolated to exact Markdown classification in one test file; confidence is high.

### Test Coverage Gaps

- Existing negative cases cover the earlier raw prefix/suffix, backtick substitution, repeated occurrence, and unmatched-backtick variants, but not semicolon composition, suffix `$()` substitution, or double-backtick delimiter runs.
- `createCutoverOwnershipFixture` proves only raw standalone candidate/written presence. No focused test calls the classifier for accepted standalone, whole single-backtick, and list-inline declarations and asserts the exact candidate/written identities and preserved remainder.
- Add both focused positive identity coverage and the complete observed negative variant set; no product-runtime test is needed because the changed code is a repository ownership test oracle.

### Symbol References

- `classifyExactValidationDocumentation` is declared at `apps/agent/internal/taskloop/cutover_test.go:360` and called only by `noDispatcherCallerViolation` in the same file.
- `exactValidationCommandCandidates` is declared in the same file and used by the classifier plus deterministic fixture setup.
- Keep any new Markdown span/parser helper test-local. Update the sole scanner call and deterministic ownership search if the classifier symbol changes. No production symbol changes or dependencies are allowed.

### Split Judgment

Keep one compact plan. Markdown span parsing, exact presence identity, caller preservation, and their positive/negative fixtures are one fail-closed scanner invariant in one test file; splitting would create no independently acceptable state.

### 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=7`, `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_API-1] Replace heuristic outside-text stripping with structural exact Markdown declaration parsing, exact identity presence accounting, and focused accepted/rejected boundary fixtures.
- [ ] [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_API-1] Structural Markdown declaration parsing

**Problem**

`apps/agent/internal/taskloop/cutover_test.go:399-413` removes the exact command after checking only backtick parity, selected prefix words, and selected suffix operators. It therefore accepts semicolon composition, suffix command substitution, and delimiter runs that are not the intended single-backtick inline declaration. The current tests also do not assert exact candidate/written identities for all allowed declaration shapes.

**Solution**

- Parse raw exact-command occurrence count first and reject every line with zero or multiple candidate occurrences from declaration handling.
- Accept only a trimmed raw exact command, a whole single-backtick exact command, or a Markdown list item whose parsed code spans contain exactly one single-backtick span equal to one exact command.
- Parse backtick delimiter runs structurally. Double/triple-backtick spans, unmatched delimiters, the exact command inside a non-single-backtick span, and repeated exact spans remain unchanged for caller scanning.
- For the list-inline form, require bounded Markdown prose outside the exact span and reject shell substitution/control/redirection tokens on either side, including `$(`, backticks outside parsed spans, `;`, `&`, `|`, `<`, and `>`. Preserve non-exempt spans and prose in the returned scanner text.
- Compare returned declaration identities directly with `exactValidationCommandCandidates[0]` and `[1]`; do not infer candidate/written presence with substring matching.
- Add a focused positive table for raw standalone, whole single-backtick, and list-inline candidate/written declarations, and extend the negative matrix with all three reviewer-observed variants while retaining every earlier case.

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

```go
if strings.Count(outsideText, "`")%2 != 0 {
	return line, nil
}
// Selected prefix and suffix heuristics.
return outsideText, []string{exactCmd}
```

After:

```go
remaining, command, ok := parseExactMarkdownValidationDeclaration(line)
if !ok {
	return line, nil
}
return remaining, []string{command}
```

The shape is illustrative. Keep the parser test-local, deterministic, and fail closed.

**Modified Files and Checklist**

- [ ] `apps/agent/internal/taskloop/cutover_test.go`: implement structural span/list parsing, direct identity presence checks, accepted-form fixtures, and the complete observed rejection matrix.

**Test Strategy**

- Add `TestClassifyExactValidationDocumentationAcceptsDeclaredForms` with candidate/written raw, whole single-backtick, and Markdown list-inline cases; assert the exact declared identity and expected remaining text.
- Extend `TestCutoverProductionOwnershipRejectsNonExactValidationVariants` with `shell_semicolon_suffix`, `command_substitution_suffix`, and `double_backtick_span`; require exact path and line evidence.
- Retain all prior negative variants, current repository ownership scanning, dispatcher-owner whole-document exception, and missing-declaration checks.

**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; every allowed declaration returns the exact candidate/written identity, and every known executable, malformed, or repeated form fails with exact path/line evidence.

### [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 structural parser regression matrix.
- 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_API-1 |
| `agent-task/m-iop-agent-cli-runtime/CODE_REVIEW-cloud-G04.md` | 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 structural 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|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: ownership references are intentional, superseded heuristic 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`.
