<!-- task=m-iop-agent-cli-runtime/22+16,19,20,21_logged_smoke plan=0 tag=TEST -->

# Logged-in macOS Multi-Project Smoke

## For the Implementing Agent

Fill implementation-owned sections in `CODE_REVIEW-cloud-G07.md` with actual outputs. Keep the active pair in place and report ready for review. If the required macOS/login runner is unavailable, implement and locally verify the harness, then record the exact failed preflight and setup/resume command; do not fabricate field evidence, ask the user directly, create stop files, or finalize the task.

## Background

Unit and integration tests cannot prove real CLI authentication, process lifecycle, cancellation, restart recovery, and project isolation together. S14 therefore requires a redacted field manifest from an actual logged-in macOS device with at least two registered project clones.

## 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:
  - `logged-smoke`: authenticated macOS discovery-through-completion multi-project field validation
- 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`
- `configs/iop-agent.providers.yaml`
- `packages/go/agentconfig/runtime_config.go`
- `packages/go/agenttask/types.go`
- `scripts/e2e-openai-cli-workspace.sh`
- `Makefile`
- `agent-test/local/rules.md`
- `agent-test/local/profiles/platform-common-smoke.md`
- `agent-test/local/profiles/testing-smoke.md`

### SDD Criteria

Approved SDD scenario S14 maps to `logged-smoke`. Its Evidence Map requires an actual logged-in macOS multi-project field manifest. The run must cover discovery, run/stream, quota/status, cancel, a new invocation after cancel, daemon restart/recovery, completion, per-project logs, and proof that one project failure does not stop the other, without recording credentials.

### Verification Context

No handoff was supplied. External Verification Preflight observed:

- runner: current container, repo `/config/workspace/iop-s0`
- OS/arch: `Linux aarch64` — mismatch; required `Darwin arm64|x86_64`
- branch/HEAD: `feature/iop-agent-cli-runtime` / `bf64b7d86511a527ff48ddf196e33531551e79a5` at analysis
- dirty state: roadmap synchronization plus these active plan artifacts only
- source sync: no macOS checkout supplied
- binary: `build/bin/iop-agent` absent at analysis
- CLI paths: `codex`, `claude`, `pi`, and `agy` are on current PATH; login state was not probed to avoid claiming field readiness from the wrong OS
- config: repo provider catalog exists; user-local macOS config path not supplied
- runtime identity/socket/process: none; no daemon is running
- ports/external hosts: no TCP port is required; the local Unix socket must be under the user-local state root; provider network hosts remain CLI-owned

Exact resume setup: on a logged-in macOS runner, sync the same reviewed commit, run `make build-agent`, prepare a user-local config with two clean registered clones, verify catalog-declared CLI logins with their status commands, and invoke the harness with explicit binary/config/workspace/expected-HEAD arguments. Current Linux cannot satisfy S14, so field execution is an expected external blocker until that setup exists. Confidence is high for harness-local checks and low for external result until executed.

### Test Coverage Gaps

- No authenticated `iop-agent` smoke exists.
- Existing workspace smoke uses a synthetic shell adapter and Edge/Node, not the standalone host.
- No test restarts the built daemon while two real provider tasks are independently active.
- No redacted manifest schema prevents accidental credential/path leakage.

### Symbol References

None. Integration wiring uses the completed predecessor package APIs; any signature drift must be recorded as a plan deviation rather than guessed.

### Split Judgment

This external packet is intentionally isolated so it can block without withholding implementation completion. It depends on the CLI closure at 16, project-log closure at 19, local control at 20, and client process manager at 21; all four `complete.log` files are currently missing. Its stable PASS output is a deterministic harness plus one redacted field manifest from the exact built commit.

### Scope Rationale

Do not change provider authentication, download CLIs, add tokens, use the current working checkout as a provider workspace, or put raw paths/provider output in tracked files. Do not use synthetic adapters as S14 completion evidence. Product integration fixes discovered by the smoke are allowed only in the listed bootstrap/main files and must remain within predecessor contracts.

### Final Routing

- evaluation_mode: `first-pass`
- finalizer: `finalize-task-policy.sh pair`
- build: `cloud-G07`, basis `capability-gap`, filename `PLAN-cloud-G07.md`
- review: `cloud-G07`, basis `official-review`, filename `CODE_REVIEW-cloud-G07.md`
- large_indivisible_context: `false`
- positive loop risks: `external macOS state`, `authenticated provider variability`, `multi-process cleanup` (count `3`)
- recovery signals: rework `0`, evidence-integrity failure `false`
- capability-gap evidence: current runner is Linux and has no built binary/user-local macOS configuration

## Implementation Checklist

- [ ] Wire the completed host, project-log, local-control, and client-process components into one daemon lifecycle without adding fallback implementations.
- [ ] Add a fail-fast, cleanup-safe macOS field harness with exact source/binary/config/login/workspace/socket/process preflight.
- [ ] Cover discovery, preview/start, stream/log, quota/status, cancel, new invocation, daemon restart/recovery, independent project failure, and completion.
- [ ] Emit and validate a bounded redacted manifest containing commit/binary/config revisions, provider readiness states, project pseudonyms, step results, and evidence locators.
- [ ] Add Makefile entry points and locally verify help/preflight/redaction/cleanup behavior without claiming S14 completion.
- [ ] Execute the harness on an actual logged-in macOS runner and paste the redacted manifest plus exact command output.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [TEST-1] Wire the Complete Daemon

#### Problem

`agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md:156,181` requires one production binary to exercise the integrated S14 lifecycle, while the predecessor packets expose components independently.

#### Solution

Update bootstrap composition and the CLI entry point to construct project logs, local control, and client processes from the same immutable runtime snapshot/state store, then start/stop them through the host. Fail startup atomically and keep provider/runtime ownership alive when a client exits.

#### Modified Files and Checklist

- [ ] `apps/agent/internal/bootstrap/module.go` — compose all completed adapters.
- [ ] `apps/agent/internal/bootstrap/module_test.go` — test wiring/order/rollback.
- [ ] `apps/agent/cmd/agent/main.go` — use production composition.
- [ ] `apps/agent/cmd/agent/main_test.go` — test serve cancellation and component cleanup.

#### Test Strategy

Add production-composition tests with temp roots and fake provider ports. Do not use live logins here.

#### Verification

```bash
go test -count=1 -race ./apps/agent/internal/bootstrap ./apps/agent/cmd/agent
```

Expected: lifecycle order and cleanup pass without races.

### [TEST-2] Add the Field Harness and Preflight

#### Problem

`agent-test/local/rules.md:1` governs external preflight, but no standalone script proves runner/source/binary/config/login/workspace assumptions before authenticated work.

#### Solution

Add `scripts/e2e-iop-agent-logged-smoke.sh` with explicit required flags. Require Darwin, supported arch, clean synced commit, exact binary SHA, executable/version output, catalog-declared auth status, two distinct clean clones, valid config, owner-only state root/socket, and no pre-existing daemon. Create only per-run temp/output roots, install traps before process start, and target exact recorded PIDs for cleanup.

#### Modified Files and Checklist

- [ ] `scripts/e2e-iop-agent-logged-smoke.sh` — implement preflight, steps, cleanup, and manifest.
- [ ] `scripts/fixtures/iop-agent-smoke-manifest.schema.json` — define bounded redacted output.

#### Test Strategy

Expose `--preflight-only` and `--validate-manifest`. On Linux, assert a deterministic OS mismatch before login/process calls. Test redaction with synthetic secret/path fixtures under `/tmp`.

#### Verification

```bash
bash -n scripts/e2e-iop-agent-logged-smoke.sh
scripts/e2e-iop-agent-logged-smoke.sh --help
preflight_output=$(mktemp)
if scripts/e2e-iop-agent-logged-smoke.sh --preflight-only >"$preflight_output" 2>&1; then exit 1; fi
test "$(rg -c 'requires Darwin' "$preflight_output")" = 1
```

Expected: syntax/help pass and Linux fails exactly at the OS gate.

### [TEST-3] Exercise the S14 Lifecycle

#### Problem

`agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md:156` requires discovery through completion, but no field sequence orchestrates it.

#### Solution

In the harness, validate configs; record provider readiness; list projects; preview both; start two distinct selected work units; observe stream/project log sequences; capture quota/status; cancel one; verify the sibling continues; start a new invocation; terminate/restart only the daemon; prove locator/state recovery; wait for terminal completion; and check per-project log/archive identity. Every wait has a deadline and focused diagnostic capture.

#### Modified Files and Checklist

- [ ] `scripts/e2e-iop-agent-logged-smoke.sh` — add the exact S14 sequence and assertions.

#### Test Strategy

The real field run is mandatory. Synthetic preflight tests cannot replace it.

#### Verification

```bash
scripts/e2e-iop-agent-logged-smoke.sh \
  --binary "$PWD/build/bin/iop-agent" \
  --repo-config "$PWD/configs/iop-agent.runtime.yaml" \
  --local-config "$IOP_AGENT_SMOKE_LOCAL_CONFIG" \
  --provider-catalog "$PWD/configs/iop-agent.providers.yaml" \
  --project-a "$IOP_AGENT_SMOKE_PROJECT_A" \
  --project-b "$IOP_AGENT_SMOKE_PROJECT_B" \
  --expected-head "$(git rev-parse HEAD)" \
  --output "$IOP_AGENT_SMOKE_OUTPUT"
```

Expected: exit 0 on logged-in macOS and a schema-valid redacted manifest.

### [TEST-4] Validate Evidence Redaction

#### Problem

`agent-contract/inner/iop-agent-cli-runtime.md:119-120,137` prohibits unsafe/raw local data, but no S14 evidence schema prevents provider output or device paths from leaking into task evidence.

#### Solution

Manifest records only provider IDs/readiness enums, hashed project aliases, commit/binary/config revisions, command step/status/duration, safe blocker codes, and relative evidence locator IDs. Reject token-like keys, authorization text, home paths, raw environment, prompts, and unbounded stdout/stderr. Save raw logs only in the operator-owned output root and cite their redacted locator/checksum.

#### Modified Files and Checklist

- [ ] `scripts/e2e-iop-agent-logged-smoke.sh` — enforce redaction and size bounds.
- [ ] `scripts/fixtures/iop-agent-smoke-manifest.schema.json` — constrain allowed fields.

#### Test Strategy

Feed a synthetic manifest containing token/path/auth fields and require validation failure; validate a safe fixture generated in `/tmp`.

#### Verification

```bash
scripts/e2e-iop-agent-logged-smoke.sh --validate-manifest "$IOP_AGENT_SMOKE_OUTPUT/manifest.json"
rg -n -i 'authorization|bearer|api[_-]?key|token|/Users/|/home/' "$IOP_AGENT_SMOKE_OUTPUT/manifest.json" && exit 1 || true
```

Expected: schema validation passes and forbidden search has zero matches.

### [TEST-5] Add Stable Make Targets

#### Problem

`Makefile:82-95` has smoke targets but none for standalone logged-in validation.

#### Solution

Add `test-iop-agent-logged-smoke-preflight` and `test-iop-agent-logged-smoke`. The field target must require explicit environment paths and never silently fall back to synthetic workspaces.

#### Modified Files and Checklist

- [ ] `Makefile` — add preflight and field targets.

#### Test Strategy

Run help/preflight on the current runner and confirm deterministic failure before authentication.

#### Verification

```bash
make test-iop-agent-logged-smoke-preflight
```

Expected on Linux: target returns the documented Darwin mismatch; on the field runner it passes all preflight gates.

## Dependencies and Execution Order

The runtime directory requires completed predecessors `16+13,14,15_cli_binary_contract`, `19+13,17,18_project_log_sink`, `20+13_local_control`, and `21+13,14,20_client_process_manager`. Each must have one same-group active or archived `complete.log`; all are currently missing. Implement TEST-1 before the harness field run, then TEST-2/4/5, then TEST-3 on macOS.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/agent/internal/bootstrap/module.go` | TEST-1 |
| `apps/agent/internal/bootstrap/module_test.go` | TEST-1 |
| `apps/agent/cmd/agent/main.go` | TEST-1 |
| `apps/agent/cmd/agent/main_test.go` | TEST-1 |
| `scripts/e2e-iop-agent-logged-smoke.sh` | TEST-2, TEST-3, TEST-4 |
| `scripts/fixtures/iop-agent-smoke-manifest.schema.json` | TEST-2, TEST-4 |
| `Makefile` | TEST-5 |

## Final Verification

```bash
gofmt -w apps/agent/internal/bootstrap/module.go apps/agent/internal/bootstrap/module_test.go apps/agent/cmd/agent/main.go apps/agent/cmd/agent/main_test.go
bash -n scripts/e2e-iop-agent-logged-smoke.sh
go test -count=1 -race ./apps/agent/internal/bootstrap ./apps/agent/cmd/agent
go vet ./apps/agent/internal/bootstrap ./apps/agent/cmd/agent
scripts/e2e-iop-agent-logged-smoke.sh --help
make build-agent
git diff --check
```

Then run the exact TEST-3 field command on the logged-in macOS runner and validate its manifest. Expected: all local checks pass and the field run exits 0; otherwise paste the exact preflight blocker and resume command without claiming S14. After completing all code changes, fill implementation-owned sections in `CODE_REVIEW-*-G??.md`.
