<!-- task=m-iop-agent-cli-runtime/14+13_cli_surface plan=0 tag=API -->

# Headless iop-agent CLI Surface

## For the Implementing Agent

Filling implementation-owned sections in `CODE_REVIEW-cloud-G06.md` is mandatory. Run verification, paste actual output, leave active files in place, and report ready for review. Finalization is code-review-only. If blocked, record exact blocker evidence and resume conditions without asking the user, creating stop files, archiving, or writing `complete.log`.

## Background

The approved milestone requires a complete headless product surface before any Flutter or Unity client exists. This packet exposes the standalone host through deterministic Cobra commands and split configuration examples while preserving manual-first milestone selection and side-effect-free preview.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md)
- Task ids:
  - `cli-surface`: binary, split configuration, validation, discovery, selection, lifecycle, and status commands
- Completion mode: check-on-pass

## Analysis

### Files Read

- `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`
- `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`
- `agent-contract/inner/agent-runtime.md`
- `agent-contract/inner/iop-agent-cli-runtime.md`
- `packages/go/agentconfig/runtime_config.go`
- `packages/go/agentconfig/runtime_config_test.go`
- `packages/go/agentconfig/watcher.go`
- `packages/go/agenttask/ports.go`
- `packages/go/agenttask/types.go`
- `configs/iop-agent.providers.yaml`
- `apps/node/cmd/node/main.go`
- `apps/node/cmd/node/main_test.go`
- `Makefile`
- `go.mod`

### SDD Criteria

The approved SDD scenario S10 maps to `cli-surface`. Its Evidence Map requires a binary plus split-config command integration test and a headless operation transcript. The checklist covers `validate`, provider/project/Milestone list and select, side-effect-free preview, `serve`, start/stop/resume, and coherent status including overlay, integration, and blockers; tests must also prove an unselected ready Milestone never starts.

### Verification Context

No handoff was supplied. Read `agent-test/local/rules.md`, `agent-test/local/profiles/platform-common-smoke.md`, and `agent-test/local/profiles/testing-smoke.md`. Current local toolchain is Go 1.26.2 on Linux arm64; the built CLI must also cross-compile for Darwin arm64. Use fresh tests (`-count=1`), a binary-level command transcript, `go vet`, and `git diff --check`; cached results are not accepted.

### Test Coverage Gaps

- Runtime config merge/validation is covered, but no binary invokes it.
- Shared manager tests cover lifecycle semantics, but no command parsing or manual-selection guard exists.
- There is no install-location-independent `iop-agent` build target or split config fixture.

### Symbol References

None. New Cobra commands and application adapters are added without renaming shared symbols.

### Split Judgment

This packet owns only the command/API surface and uses fake host ports for deterministic PASS. It depends on predecessor `13_standalone_host_foundation`; no active or archived `complete.log` currently satisfies index 13, so implementation must wait. Project logs, socket control, and client processes remain independent packets.

### Scope Rationale

Do not implement local proto-socket transport, client subprocesses, Python cutover, authenticated provider smoke, or a new selector. Do not embed secrets or device paths in repo-global config. The CLI delegates to the host/shared runtime and may use fakes only in tests.

### Final Routing

- evaluation_mode: `first-pass`
- finalizer: `finalize-task-policy.sh pair`
- build: closure complete, `local-G06`, basis `local-fit`, filename `PLAN-local-G06.md`
- review: closure complete, `cloud-G06`, basis `official-review`, filename `CODE_REVIEW-cloud-G06.md`
- large_indivisible_context: `false`
- positive loop risks: `broad command matrix` (count `1`)
- recovery signals: rework `0`, evidence-integrity failure `false`
- capability-gap evidence: none

## Implementation Checklist

- [ ] Add secret-free repo-global and user-local example configurations with strict validation tests.
- [ ] Implement the complete Cobra command tree over narrow host ports, including manual selection and side-effect-free preview.
- [ ] Add the `iop-agent` entry point and Makefile build target with command-level tests and Darwin cross-build.
- [ ] Update the standalone contract with actual S10 source/test paths and run a headless operation transcript.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Add Split Configuration Fixtures

#### Problem

`packages/go/agentconfig/runtime_config.go:18-37` defines separate repo-global and user-local schemas, but `configs/` contains only the provider catalog and no runnable runtime examples.

#### Solution

Add a secret-free `configs/iop-agent.runtime.yaml` with defaults, selection, isolation, and retention. Add `configs/iop-agent.local.example.yaml` with placeholder absolute roots and project registration. Keep the provider catalog in `configs/iop-agent.providers.yaml`; the command bootstrap loads the catalog and runtime inputs as separate owned sources.

```yaml
# Before: no standalone runtime examples.
# After:
version: "1"
defaults:
  auto_resume_interrupted: true
```

#### Modified Files and Checklist

- [ ] `configs/iop-agent.runtime.yaml` — add repo-global runtime defaults.
- [ ] `configs/iop-agent.local.example.yaml` — add secret-free device/project example.
- [ ] `apps/agent/internal/command/config_test.go` — validate examples and read-only behavior.

#### Test Strategy

Write `TestTrackedRuntimeExamplesLoad` and `TestValidateDoesNotMutateRepoConfig`; copy the local example into a temp root after substituting absolute paths.

#### Verification

```bash
go test -count=1 ./apps/agent/internal/command -run 'TestTrackedRuntimeExamplesLoad|TestValidateDoesNotMutateRepoConfig'
```

Expected: both tests pass.

### [API-2] Implement the Command Tree

#### Problem

`agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md:152,177` requires the S10 headless command surface, but no standalone command package exists.

#### Solution

Create one Cobra root with explicit `--repo-config`, `--local-config`, and `--provider-catalog` flags. Implement `validate`, `provider list`, `project list`, `milestone list`, `milestone select`, `preview`, `serve`, `start`, `stop`, `resume`, and `status`. Define a narrow command service interface; preview must not call mutation methods, and `start` must reject a project without an explicitly selected Milestone.

#### Modified Files and Checklist

- [ ] `apps/agent/internal/command/root.go` — construct root, flags, and subcommands.
- [ ] `apps/agent/internal/command/service.go` — define request/response DTOs and service port.
- [ ] `apps/agent/internal/command/root_test.go` — test the complete matrix and stable text/JSON output.
- [ ] `apps/agent/internal/command/config_test.go` — cover config commands.

#### Test Strategy

Write table tests `TestCommandMatrix`, `TestPreviewIsSideEffectFree`, `TestStartRequiresSelectedMilestone`, and `TestStatusIncludesOverlayIntegrationAndBlockers` using one recording fake.

#### Verification

```bash
go test -count=1 ./apps/agent/internal/command
```

Expected: all commands parse and delegate exactly once; preview and unselected start mutate nothing.

### [API-3] Add the Binary and Build Target

#### Problem

`Makefile:30-48` builds only Edge and Node binaries; no `iop-agent` entry point exists.

#### Solution

Add `apps/agent/cmd/agent/main.go` with an injectable `run(args, stdout, stderr)` seam. Build to `build/bin/iop-agent`, include it in `build-local`, and keep default paths overrideable so the binary works outside a checkout.

```make
# Before (Makefile:30)
build-local: build-edge build-node

# After
build-local: build-edge build-node build-agent
```

#### Modified Files and Checklist

- [ ] `apps/agent/cmd/agent/main.go` — add the process entry point.
- [ ] `apps/agent/cmd/agent/main_test.go` — verify exit codes and output separation.
- [ ] `Makefile` — add `build-agent` and include it in local build.

#### Test Strategy

Test success, usage error, config error, and context cancellation. Build for local and Darwin arm64.

#### Verification

```bash
go test -count=1 ./apps/agent/cmd/agent
make build-agent
GOOS=darwin GOARCH=arm64 go build -trimpath -o /tmp/iop-agent-darwin-arm64 ./apps/agent/cmd/agent
```

Expected: tests and both builds pass.

### [API-4] Record S10 Sources and Transcript

#### Problem

`agent-contract/inner/iop-agent-cli-runtime.md:9-14` has no implemented S10 source paths.

#### Solution

Add the actual CLI/config paths and S10 evidence row without restating shared runtime semantics. Run a temp-fixture transcript covering every command, stable errors, and the no-unselected-start invariant.

#### Modified Files and Checklist

- [ ] `agent-contract/inner/iop-agent-cli-runtime.md` — record actual S10 sources/tests and evidence.

#### Test Strategy

No additional test file; API-2/API-3 tests are the contract evidence.

#### Verification

```bash
build/bin/iop-agent --help
build/bin/iop-agent validate --repo-config configs/iop-agent.runtime.yaml --local-config /tmp/iop-agent-cli/local.yaml --provider-catalog configs/iop-agent.providers.yaml
```

Expected: help lists the full surface and validate succeeds against the prepared temp fixture.

## Dependencies and Execution Order

Predecessor `13_standalone_host_foundation` must produce `agent-task/m-iop-agent-cli-runtime/13_standalone_host_foundation/complete.log` (or its exact archived counterpart) before implementation begins. No other dependency is encoded by `14+13_cli_surface`.

## Modified Files Summary

| File | Item |
|------|------|
| `configs/iop-agent.runtime.yaml` | API-1 |
| `configs/iop-agent.local.example.yaml` | API-1 |
| `apps/agent/internal/command/config_test.go` | API-1, API-2 |
| `apps/agent/internal/command/root.go` | API-2 |
| `apps/agent/internal/command/service.go` | API-2 |
| `apps/agent/internal/command/root_test.go` | API-2 |
| `apps/agent/cmd/agent/main.go` | API-3 |
| `apps/agent/cmd/agent/main_test.go` | API-3 |
| `Makefile` | API-3 |
| `agent-contract/inner/iop-agent-cli-runtime.md` | API-4 |

## Final Verification

```bash
gofmt -w apps/agent/cmd/agent/*.go apps/agent/internal/command/*.go
go test -count=1 ./apps/agent/cmd/agent ./apps/agent/internal/command
go test -count=1 -race ./apps/agent/cmd/agent ./apps/agent/internal/command
go vet ./apps/agent/cmd/agent ./apps/agent/internal/command
make build-agent
GOOS=darwin GOARCH=arm64 go build -trimpath -o /tmp/iop-agent-darwin-arm64 ./apps/agent/cmd/agent
build/bin/iop-agent --help
git diff --check
```

Expected: fresh tests, race, vet, local/Darwin builds, help transcript, and diff check pass. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
