<!-- task=m-iop-agent-chronos-extraction-decoupling/17+15,16_canonical_promotion_closure plan=2 tag=REVIEW_REFACTOR milestone-task=handoff-gate -->

# Plan - Provider-Only Ownership Wording Closure

## For the Implementing Agent

Filling the implementation-owned sections in `CODE_REVIEW-cloud-G08.md` is mandatory. Run every verification command, record actual notes and stdout/stderr, keep the active files in place, and report ready for review; finalization belongs only to the code-review skill. If blocked, record the exact blocker, attempted commands/output, and resume condition only 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

Canonical promotion and the full regression matrix are reproducible, but active package and CLI descriptions still assign IOP execution to a standalone Agent and terminal-session model. This follow-up removes only those residual ownership statements, adds a focused CLI regression, and records equivalent staging and canonical corrective commits without disturbing protected roadmap, Agent UI, recovery, or lock state.

## Archive Evidence Snapshot

- `agent-task/m-iop-agent-chronos-extraction-decoupling/17+15,16_canonical_promotion_closure/code_review_cloud_G10_0.log` recorded the first FAIL because canonical promotion had not occurred.
- `agent-task/m-iop-agent-chronos-extraction-decoupling/17+15,16_canonical_promotion_closure/code_review_cloud_G10_1.log` records the current FAIL: promotion commit `c8e98d4e10b30114de7bafe426a4045abd6c1205`, the 34-path conflict digest, recovery artifacts, fresh regressions, mirroring, and the disabled lock were verified, but three active source descriptions still claim Agent/terminal ownership.
- The Required finding affects `packages/go/execution/doc.go`, `packages/go/execution/types.go`, and `apps/node/cmd/node/main.go`; `apps/node/cmd/node/main_test.go` is the focused regression target. The current canonical and staging source text is identical at each affected hunk, while canonical `types.go` intentionally retains unrelated credential support absent from staging.
- Roadmap carryover remains unchanged: the Milestone is review-open, the Chronos dependency lock remains `disable`, and this task must not archive the Milestone, enable the lock, push either branch, or mutate Chronos or any remote repository.

## Analysis

### Files Read

- `/config/workspace/iop/packages/go/execution/doc.go`
- `/config/workspace/iop/packages/go/execution/types.go`
- `/config/workspace/iop/packages/go/execution/conformance_test.go`
- `/config/workspace/iop/apps/node/cmd/node/main.go`
- `/config/workspace/iop/apps/node/cmd/node/main_test.go`
- `packages/go/execution/doc.go`
- `packages/go/execution/types.go`
- `packages/go/execution/conformance_test.go`
- `apps/node/cmd/node/main.go`
- `apps/node/cmd/node/main_test.go`

The canonical files were read in full. Staging `doc.go`, `main.go`, `main_test.go`, and `conformance_test.go` were byte-compared with canonical; staging `types.go` was read in full because canonical contains an unrelated `ProviderCredential` delta.

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-chronos-extraction-decoupling/SDD.md`; status `[승인됨]`; SDD lock `해제`.
- First-line Milestone task: `handoff-gate`.
- Targeted scenarios: S04 (`retain-node`) and S05 (`handoff-gate`). S04 requires provider-focused regression plus a forbidden-reference audit proving no CLI Agent, terminal, workspace, remote-control, or Chronos surface. S05 requires the tracked `HANDOFF.md`, rollback evidence, regression evidence, and lock identity to remain traceable.
- Evidence Map rows S04 and S05 therefore require the checklist to pair the source wording correction with a focused Node/execution regression and deterministic forbidden-text scan, then preserve the existing promotion/recovery evidence while adding exact corrective commit identities to the mirrored receipt. Final Milestone archive and lock enable remain excluded.

### Verification Context

No separate handoff was supplied. Repository-native evidence came from the active PLAN/review pair, the prior review log, approved SDD, active Milestone/Phase, execution contract/spec, domain and local-test rules, the five source/test files above, both HANDOFF files, git state, and fresh review commands.

Concrete criteria already applied: both affected checkouts were inspected; canonical HEAD is `c8e98d4e10b30114de7bafe426a4045abd6c1205` on `dev`; staging HEAD is `7b90b7e5af9035fae2b5349c65eb322096d21b1b` on `feature/iop-agent-chronos-extraction-decoupling`; neither checkout has staged or unmerged paths. Canonical has exactly seven intentional unstaged tracked paths: `HANDOFF.md`, three roadmap files, and three Agent UI files. `git version 2.43.0`, `go version go1.26.2 linux/arm64`, Linux/aarch64, and local filesystem access are available. Confidence is high because the offending strings and intended regression entry point are direct source evidence.

External Verification Preflight: the only verification outside the current checkout is the local canonical repository at `/config/workspace/iop`; no remote runner, binary artifact, credential, config, port, process, or external host is required. The implementer must require the exact HEADs above, empty index/unmerged state, and the canonical seven-path dirty inventory before mutation. If any identity or protected path differs, record a blocker instead of rebasing, resetting, stashing, or broadening scope.

### Test Coverage Gaps

- Package and error comments are non-executable; current runtime tests cannot detect ownership wording. The deterministic exact-file forbidden-text scan is the regression oracle.
- Cobra root help exposes `Command.Short`, but existing `main_test.go` checks only command presence and behavior. Add `TestRootCmdUsesProviderOnlyDescription` to require provider wording and reject Agent wording.
- Execution behavior does not change. Existing fresh tests in `./packages/go/execution` and `./apps/node/cmd/node` cover compilation and run/provider behavior; no broader runtime test source change is justified.

### Symbol References

None. No symbol, type, command, flag, or wire field is renamed or removed.

### Split Judgment

Do not split. Four small source/test hunks, their equivalent two-repository commits, and the mirrored corrective receipt are one compact closure invariant: the reviewed text must be provider-only and traceable in both checkouts before the S04/S05 evidence can pass.

### Scope Rationale

Exclude runtime logic, wire/proto/config, generated files, roadmap/SDD state, Agent UI content, existing recovery artifacts, remote branches, Chronos sources, and lock mutation. The fresh full regression evidence from the preceding review remains valid because this packet changes comments, Cobra help text, one focused test, and receipt metadata only; focused uncached Go tests and deterministic boundary/state checks are sufficient.

### Final Routing

- `evaluation_mode=isolated-reassessment`; `finalizer=finalize-task-policy.sh`; `finalizer_mode=pair`.
- Build closures: scope, context, verification, evidence trust, ownership, and decision are all closed; no capability gap. Scores: scope coupling 2, state/concurrency 2, blast/irreversibility 1, evidence/diagnosis 1, verification complexity 2; grade G08. Base `local-fit` is promoted by `recovery-boundary` to `cloud`; canonical filename `PLAN-cloud-G08.md`.
- Review closures: all closed; no capability gap. Scores 2/2/1/1/2; route `official-review`, cloud G08; canonical filename `CODE_REVIEW-cloud-G08.md`.
- `large_indivisible_context=false`; positive loop risks: `temporal_state`, `boundary_contract`; count 2. `review_rework_count=2`; `evidence_integrity_failure=false`; recovery boundary matched, risk boundary did not. No capability-gap evidence applies.

## Implementation Checklist

- [ ] Correct the provider-only ownership wording in staging and canonical source, and add the focused Node CLI regression test.
- [ ] Create exact staging/canonical corrective commits, update mirrored HANDOFF evidence, and verify protected state, ancestry, recovery, and lock preservation.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_REFACTOR-1] Correct provider-only source wording and add a focused regression

**Problem**

`packages/go/execution/doc.go:1-4` says the package is shared with standalone Agent hosts and owns terminal-session primitives. `packages/go/execution/types.go:15` describes cancellation through persistent-session termination semantics. `apps/node/cmd/node/main.go:29` labels the provider device runtime as `IOP Node Agent`. These active descriptions contradict SDD S04 and the provider-only execution contract.

**Solution**

Apply the same logical edits independently in staging and canonical so canonical-only credential code remains untouched.

Before (`packages/go/execution/doc.go:1-4`):

```go
// Package execution contains the host-neutral execution contract shared by
// IOP Node and standalone agent hosts. It owns provider lifecycle, streaming
// events, typed failures, registry lifecycle, and terminal session primitives;
// host wire translation remains outside this package.
```

After:

```go
// Package execution contains provider-only, host-neutral execution contracts
// shared by Node and Edge-facing provider transports. It owns provider
// lifecycle, streaming events, typed failures, and registry lifecycle;
// host wire translation remains outside this package.
```

Before (`packages/go/execution/types.go:15`):

```go
// ErrRunCancelled is returned by adapters when a run is cancelled without terminating the session.
```

After:

```go
// ErrRunCancelled is returned by providers when a single run is cancelled.
```

Before (`apps/node/cmd/node/main.go:29`):

```go
Short: "IOP Node Agent — runs adapter executions on this device",
```

After:

```go
Short: "IOP Node — runs provider executions on this device",
```

Add `TestRootCmdUsesProviderOnlyDescription` to assert that `rootCmd().Short` contains `provider` and does not contain `agent`, case-insensitively.

**Modified Files and Checklist**

- [ ] Update `packages/go/execution/doc.go` in staging and canonical with provider-only ownership.
- [ ] Update `packages/go/execution/types.go` in staging and canonical with run-scoped cancellation wording, preserving unrelated canonical credential fields.
- [ ] Update `apps/node/cmd/node/main.go` in staging and canonical with the provider-device description.
- [ ] Add the identical focused regression to `apps/node/cmd/node/main_test.go` in both checkouts.
- [ ] Run `gofmt` only on the changed Go files and prove the exact forbidden phrases are absent from the three production files.

**Test Strategy**

Add the regression test `TestRootCmdUsesProviderOnlyDescription` in `apps/node/cmd/node/main_test.go`; it guards the user-visible CLI description. Do not add a test that parses Go comments. The exact-file, case-insensitive forbidden-text scan directly guards the two documentation corrections. Fresh Go execution is required; cached output is not accepted.

**Verification**

Run from each checkout:

```bash
gofmt -w packages/go/execution/doc.go packages/go/execution/types.go apps/node/cmd/node/main.go apps/node/cmd/node/main_test.go
if rg --sort path -n -i 'standalone agent|terminal session primitives|terminating the session|IOP Node Agent' packages/go/execution/doc.go packages/go/execution/types.go apps/node/cmd/node/main.go; then exit 1; fi
rg --sort path -n 'provider-only|single run is cancelled|IOP Node — runs provider executions' packages/go/execution/doc.go packages/go/execution/types.go apps/node/cmd/node/main.go
TMPDIR="$PWD/.tmp" GOTMPDIR="$PWD/.tmp" go test -count=1 ./packages/go/execution ./apps/node/cmd/node
git diff --check
```

Expected: no forbidden match; all three provider/run-scoped assertions match; the focused fresh tests and diff check pass.

### [REVIEW_REFACTOR-2] Commit and record equivalent corrective closure

**Problem**

`HANDOFF.md:83-86` records the staging promotion commit and canonical promotion commit but has no identity for a post-promotion boundary correction. Leaving the text only as dirty worktree state would break the S05 traceability chain, while rewriting either reviewed commit would invalidate the verified promotion and recovery evidence.

**Solution**

In staging, require parent HEAD `7b90b7e5af9035fae2b5349c65eb322096d21b1b`, stage only the four REVIEW_REFACTOR-1 paths, and create one corrective commit. In canonical, require parent HEAD `c8e98d4e10b30114de7bafe426a4045abd6c1205` and the exact seven protected dirty paths, stage only the same four logical paths, and create one child corrective commit while leaving all protected paths unstaged. Do not amend, reset, stash, push, or touch the retained recovery artifacts.

Then update canonical and staging `HANDOFF.md` identically: preserve `staging_promotion_commit` and `canonical_promotion_commit`; add `staging_boundary_correction_commit`, `canonical_boundary_correction_commit`, and `canonical_boundary_correction_verified_at`; and update the Canonical Promotion Receipt prose to identify the child correction. The new fields must contain actual commits with the required parents and exact four-path change sets.

**Modified Files and Checklist**

- [ ] Preflight exact staging/canonical HEAD, empty staged/unmerged state, and canonical protected seven-path inventory.
- [ ] Commit only the four source/test paths in staging with parent `7b90b7e5...`.
- [ ] Commit only the four source/test paths in canonical with parent `c8e98d4...`; preserve its seven unstaged tracked paths.
- [ ] Prove the two corrective diffs have the same stable patch id and neither commit contains task, roadmap, UI, receipt, generated, or unrelated source paths.
- [ ] Add actual corrective commit ids and verification time to both `HANDOFF.md` files and require byte equality.
- [ ] Re-run focused tests and boundary scans on committed heads; verify promotion/correction ancestry, retained recovery commits, clean indexes, UI mirrors, and disabled Chronos lock.

**Test Strategy**

No additional test source is required beyond REVIEW_REFACTOR-1. This item is a history/evidence transaction guarded by exact parent, path-set, stable patch-id, ancestry, dirty-inventory, mirror, stash-object, and lock checks. Any mismatch is a blocker; do not repair it with a history rewrite.

**Verification**

Run the preflight before editing or committing:

```bash
test "$(git rev-parse HEAD)" = 7b90b7e5af9035fae2b5349c65eb322096d21b1b
test -z "$(git diff --cached --name-only)"
test -z "$(git ls-files -u)"
test "$(git -C /config/workspace/iop rev-parse HEAD)" = c8e98d4e10b30114de7bafe426a4045abd6c1205
test -z "$(git -C /config/workspace/iop diff --cached --name-only)"
test -z "$(git -C /config/workspace/iop ls-files -u)"
diff -u <(printf '%s\n' HANDOFF.md agent-roadmap/phase/automation-runtime-bridge/PHASE.md agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md agent-roadmap/priority-queue.md agent-ui/.sync-state.json agent-ui/definition/components/console-shell/index.md agent-ui/definition/components/index.md) <(git -C /config/workspace/iop diff --name-only | sort)
```

After the two source/test commits and mirrored receipt update, run:

```bash
staging_correction="$(git rev-parse HEAD)"
canonical_correction="$(git -C /config/workspace/iop rev-parse HEAD)"
test "$(git rev-parse HEAD^)" = 7b90b7e5af9035fae2b5349c65eb322096d21b1b
test "$(git -C /config/workspace/iop rev-parse HEAD^)" = c8e98d4e10b30114de7bafe426a4045abd6c1205
expected_paths="$(printf '%s\n' apps/node/cmd/node/main.go apps/node/cmd/node/main_test.go packages/go/execution/doc.go packages/go/execution/types.go)"
test "$(git diff-tree --no-commit-id --name-only -r HEAD | sort)" = "$expected_paths"
test "$(git -C /config/workspace/iop diff-tree --no-commit-id --name-only -r HEAD | sort)" = "$expected_paths"
test "$(git diff 7b90b7e5af9035fae2b5349c65eb322096d21b1b..HEAD -- $expected_paths | git patch-id --stable | awk '{print $1}')" = "$(git -C /config/workspace/iop diff c8e98d4e10b30114de7bafe426a4045abd6c1205..HEAD -- $expected_paths | git patch-id --stable | awk '{print $1}')"
test -z "$(git diff --cached --name-only)"
test -z "$(git -C /config/workspace/iop diff --cached --name-only)"
test -z "$(git ls-files -u)"
test -z "$(git -C /config/workspace/iop ls-files -u)"
diff -u <(printf '%s\n' HANDOFF.md agent-roadmap/phase/automation-runtime-bridge/PHASE.md agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md agent-roadmap/priority-queue.md agent-ui/.sync-state.json agent-ui/definition/components/console-shell/index.md agent-ui/definition/components/index.md) <(git -C /config/workspace/iop diff --name-only | sort)
cmp /config/workspace/iop/HANDOFF.md HANDOFF.md
test "$(sed -n 's/^staging_boundary_correction_commit: //p' HANDOFF.md)" = "$staging_correction"
test "$(sed -n 's/^canonical_boundary_correction_commit: //p' HANDOFF.md)" = "$canonical_correction"
git -C /config/workspace/iop merge-base --is-ancestor c8e98d4e10b30114de7bafe426a4045abd6c1205 "$canonical_correction"
git -C /config/workspace/iop cat-file -e a91e4af2bc23c7fab2ef0ea026e2b453e9393848^{commit}
git -C /config/workspace/iop cat-file -e ff81ecb5e8b16fc81ecce4273afe24ff06236287^{commit}
cmp /config/workspace/iop/agent-ui/.sync-state.json agent-ui/.sync-state.json
cmp /config/workspace/iop/agent-ui/definition/components/console-shell/index.md agent-ui/definition/components/console-shell/index.md
cmp /config/workspace/iop/agent-ui/definition/components/index.md agent-ui/definition/components/index.md
agent-ops/bin/roadmap-dependency-checker.sh --find-milestone 'iop:agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md' both /config/workspace/.agent-roadmap-sync/locks.yaml
rg -n -A4 'id: chronos:chronos-architecture-ownership-boundary' /config/workspace/.agent-roadmap-sync/locks.yaml
```

Expected: both commits have exact parents and four-path change sets; their stable patch ids match; receipt fields resolve to the actual commits; canonical promotion and recovery ancestry remain intact; indexes are clean; UI and HANDOFF mirrors match; dependency output identifies the Chronos boundary and lock status remains `disable`.

## Modified Files Summary

| File | Items |
|------|-------|
| `packages/go/execution/doc.go` | REVIEW_REFACTOR-1, REVIEW_REFACTOR-2 |
| `packages/go/execution/types.go` | REVIEW_REFACTOR-1, REVIEW_REFACTOR-2 |
| `apps/node/cmd/node/main.go` | REVIEW_REFACTOR-1, REVIEW_REFACTOR-2 |
| `apps/node/cmd/node/main_test.go` | REVIEW_REFACTOR-1, REVIEW_REFACTOR-2 |
| `HANDOFF.md` | REVIEW_REFACTOR-2 |
| `agent-task/m-iop-agent-chronos-extraction-decoupling/17+15,16_canonical_promotion_closure/CODE_REVIEW-cloud-G08.md` | REVIEW_REFACTOR-1, REVIEW_REFACTOR-2 |

## Final Verification

Run every REVIEW_REFACTOR-1 command from both checkouts and every REVIEW_REFACTOR-2 command in the stated order. Require fresh focused Go PASS, no forbidden ownership text, exact corrective commit parents/path sets/patch equivalence, clean indexes and unmerged state, canonical protected dirty paths preserved, byte-identical HANDOFF/UI evidence, retained recovery commit objects, promotion ancestry, and a disabled Chronos lock. Record actual stdout/stderr or exact saved output paths in the active review artifact; cached Go output is not accepted.

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