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

# Canonical IOP Promotion and Closure Readiness

## For the Implementing Agent

Filling implementation-owned sections in `CODE_REVIEW-cloud-G10.md` is mandatory. Run every verification command, paste actual output or an exact saved-output path, keep the active PLAN/review 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 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

All implementation tasks and fresh regressions for the extraction milestone pass in `/config/workspace/iop-s1`, but `HANDOFF.md:83-88` still records canonical promotion as pending. The approved SDD requires a reviewed commit to be applied to `/config/workspace/iop` before the canonical `iop:` milestone can justify the Chronos lock. The canonical checkout is one commit behind `origin/dev` and has three user-owned roadmap edits, so promotion, reconciliation, and rollback evidence must be handled as one ordered closure packet.

## Archive Evidence Snapshot

- `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/15+14_handoff_closure/complete.log`: PASS; the tracked final composite receipt and exact `HANDOFF.md` digest were accepted after Task 14 removal evidence.
- `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/16_manifest_baseline_repair/complete.log`: PASS; corrected pinned-transfer manifest baseline is 300 rows (`file=290`, `state=10`, `retain-generic=135`) with SHA-256 `d8598134dee99d96fc05a045091dd3d8932d4708d2c980c2a78c8b11825d2ccf`.
- No Required, Suggested, or Nit findings remain in those predecessor completion records. This plan does not reinterpret archived evidence; it promotes the already accepted result and records the canonical identity.

## Analysis

### Files Read

- `HANDOFF.md`
- `agent-roadmap/current.md`
- `agent-roadmap/priority-queue.md`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md`
- `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-chronos-extraction-decoupling/SDD.md`
- `agent-ui/.sync-state.json`
- `agent-ui/definition/components/console-shell/index.md`
- `agent-ui/definition/components/index.md`
- `/config/workspace/.agent-roadmap-sync/locks.yaml`
- `/config/workspace/iop/agent-roadmap/current.md`
- `/config/workspace/iop/agent-roadmap/priority-queue.md`
- `/config/workspace/iop/agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `/config/workspace/iop/agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md`
- `/config/workspace/iop/agent-ui/.sync-state.json`
- `/config/workspace/iop/agent-ui/definition/components/console-shell/index.md`

No production source or test behavior changes are planned. Existing milestone behavior is verified through repository-native commands rather than new test source.

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-chronos-extraction-decoupling/SDD.md`, status `[승인됨]`, SDD lock `해제`.
- Milestone task metadata: `handoff-gate`.
- Acceptance Scenario: S05. Its `Then` condition requires every disposition input, state transfer, deletion/regression result, rollback point, and Chronos lock release condition to remain traceable.
- Evidence Map row: S05 requires the state fixture, effective matrix, Task 13 receipt, Task 14 evidence, tracked `HANDOFF.md`, and lock check, with a final composite receipt suitable for Roadmap Completion.
- Cross-repo dependency: the predecessor identity is the canonical `iop:agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md`; `iop-s1` cannot satisfy it by itself.
- These rows require the checklist to preserve all predecessor receipts, record both promotion commits, rerun canonical regressions, reconcile milestone-scoped UI state, and leave the parent lock disabled until a later successful `complete-milestone` archive transaction.

### Verification Context

- No separate handoff object was supplied. Repository-native fallback evidence came from the milestone, approved SDD, `HANDOFF.md`, scoped predecessor `complete.log` files, Agent UI sync state, parent workspace lock, current git state, and executable Make targets.
- Fresh checks already passed in `/config/workspace/iop-s1`: `go test -count=1 ./...`, `make client-test` (44 tests), `make client-build-web`, `make test-control-plane-edge-wire`, `make readability-audit`, `IOP_DEV_RECONNECT_BIND_TIMEOUT=60 scripts/dev/edge-node-reconnect-diagnostic.sh`, and `git diff --check`.
- The direct reconnect spec pointer was also verified with `go test -count=1 ./apps/edge/internal/service -run '^TestAcceptedReconnectActivatesCandidateAndPumpsWaiter$'`.
- Required tools are present: Git 2.43.0, Go 1.26.2, GNU Make, Flutter, and Dart on Linux 6.10.14 aarch64.
- Cached Go output is not accepted for canonical closure; use `-count=1` and a canonical-checkout-local `TMPDIR`/`GOTMPDIR`.

#### External Verification Preflight

- Runner: current host.
- Staging repo/workdir: `/config/workspace/iop-s1`, branch `feature/iop-agent-chronos-extraction-decoupling`, pre-plan HEAD `1debc7ada01d98442560bbc4ac52dcef9cae25cc`, dirty milestone change set.
- Canonical repo/workdir: `/config/workspace/iop`, branch `dev`, HEAD `6d6bb3a44d1384e8248d482f57de522dc800aade`, `dev...origin/dev [behind 1]`.
- Canonical dirty state is exactly:
  - `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`
- Those edits add canonical `[separation-01]` labels and queue grouping. They are user-owned and must be preserved, not replaced by staging roadmap bytes.
- Source sync status: unresolved until implementation fetches `origin`, verifies that the canonical branch relationship and dirty set have not changed, and forms one reviewed staging promotion commit.
- Binary/artifact paths: repository-local Go/Flutter builds only; no pre-existing binary is trusted.
- Config/runtime identity: repository test fixtures and loopback scripts; no live provider credential or external host is required.
- Ports/process state: `make test-control-plane-edge-wire` and the reconnect diagnostic allocate their documented loopback processes; pre-existing shared processes are not assumed.
- Recovery: before canonical mutation, save the exact three-file binary diff and SHA-256 under a `mktemp -d /tmp/iop-canonical-promotion.XXXXXX` directory and create a named Git stash with only those three paths. Use `git stash apply`, not `pop`, and retain the stash until all canonical verification and patch-equivalence checks pass.
- If branch, HEAD, remote relation, dirty paths, patch digest, or lock identity differs, stop and record the mismatch; do not reset, overwrite, drop a stash, archive the milestone, or enable the lock.

### Test Coverage Gaps

- Promotion does not change runtime behavior. Existing fresh Go, Flutter, Control Plane/Edge wire, reconnect, readability, and forbidden-surface checks cover the promoted code paths.
- Git conflict resolution and the cross-workspace lock transition have no automated end-to-end test. They are covered by exact pre/post git tree comparisons, the dependency checker, retained patch/stash rollback evidence, and a mandatory later `complete-milestone` check-only pass.
- No new test source is required because this packet changes integration state and evidence only.

### Symbol References

- None. No symbol is renamed or removed by this packet.

### Split Judgment

- This remains one plan because canonical apply, regression proof, UI reconciliation, and lock ordering share one safety invariant: the canonical identity must not become closure-ready unless the exact reviewed staging tree is present and verified, and the Chronos lock must remain disabled until the later archive transaction succeeds.
- Dependency `15` is satisfied by `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/15+14_handoff_closure/complete.log`.
- Dependency `16` is satisfied by `agent-task/archive/2026/08/m-iop-agent-chronos-extraction-decoupling/16_manifest_baseline_repair/complete.log`.
- A staging-only commit is not treated as an independently complete milestone result, so it is not split from canonical reconciliation.

### Scope Rationale

- Included: promotion of the existing reviewed change set, preservation of canonical user-owned roadmap edits, canonical regression verification, Agent UI milestone reconciliation, and exact promotion evidence.
- Excluded: new runtime behavior, Chronos repository import, Chronos Server/Node implementation, provider credentials, remote deployment, and final milestone archive/lock enable. Final archive and lock enable remain owned by a subsequent `complete-milestone` run after this plan receives PASS.
- `/config/workspace/iop/**` and `/config/workspace/.agent-roadmap-sync/locks.yaml` are external preflight/action targets, not dispatcher write claims for this `/config/workspace/iop-s1` task. The implementing agent must use the explicit guarded procedure below and must not broaden external writes.

### Final Routing

- `evaluation_mode=first-pass`; `finalizer=finalize-task-policy.sh`, mode `pair`.
- Build closures: scope/context/verification/evidence/ownership/decision all closed by the exact repositories, protected dirty-path procedure, deterministic commands, and no unresolved product choice. Scores: scope 2, state 2, blast 2, evidence 2, verification 2 => G10. Base/final route: `grade-boundary`, cloud, `PLAN-cloud-G10.md`.
- Review closures: all closed. Scores: scope 2, state 2, blast 2, evidence 2, verification 2 => G10. Route: `official-review`, cloud, `CODE_REVIEW-cloud-G10.md`, Codex `gpt-5.6-sol` xhigh.
- `large_indivisible_context=false`; the invariant is explicit and commands are deterministic.
- Positive loop-risk signatures: `temporal_state`, `boundary_contract`, `structured_interpretation`; count 3. Risk boundary not matched.
- `review_rework_count=0`; `evidence_integrity_failure=false`; recovery boundary not matched; capability gap none.

## Implementation Checklist

- [ ] Freeze and promote the reviewed staging change set into canonical IOP without losing the canonical roadmap patch.
- [ ] Verify canonical code, contracts, UI, and provider-only boundaries, then reconcile milestone-scoped Agent UI state while keeping the Chronos lock disabled.
- [ ] Record exact staging/canonical promotion evidence in HANDOFF.md and mirror reconciled UI evidence in this workspace.
- [ ] Run the complete final verification matrix and preserve recovery evidence.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REFACTOR-1] Protect canonical state and apply the reviewed staging commit

**Problem**

`HANDOFF.md:83-88` says canonical promotion is pending. `/config/workspace/iop` is both behind `origin/dev` and dirty in three roadmap files, so a direct pull/cherry-pick can lose user-owned separation labels or mix an unreviewed tree into the canonical identity.

**Solution**

1. Re-run the external preflight and require the exact branch/dirty-path facts above.
2. Use the project `commit-push` workflow to form one intentional staging promotion commit. Push only if the execution request authorizes push; a local commit is sufficient for a local canonical fetch/cherry-pick.
3. Save the canonical three-file binary diff and its SHA-256 under a task-specific `/tmp` directory, then stash only those explicit paths with a descriptive name. Do not use a broad reset or checkout.
4. Fetch `origin` and the staging promotion commit, fast-forward canonical `dev` only when it is still an ancestor of `origin/dev`, then cherry-pick the staging commit.
5. Resolve only the three known roadmap conflicts by retaining canonical `[separation-01]`/queue semantics and applying the newer milestone completion evidence. Apply the retained stash, verify patch equivalence, and keep the stash until all checks pass.

Before (`/config/workspace/iop`):

```text
dev...origin/dev [behind 1]
M agent-roadmap/phase/automation-runtime-bridge/PHASE.md
M agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md
M agent-roadmap/priority-queue.md
```

After:

```text
canonical dev contains the reviewed staging promotion commit
the three canonical separation/queue edits remain represented
no unmerged paths exist
the saved patch and named stash remain recoverable until verification passes
```

**Modified Files and Checklist**

- [ ] Preserve and reconcile `/config/workspace/iop/agent-roadmap/phase/automation-runtime-bridge/PHASE.md`.
- [ ] Preserve and reconcile `/config/workspace/iop/agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md`.
- [ ] Preserve and reconcile `/config/workspace/iop/agent-roadmap/priority-queue.md`.
- [ ] Do not modify `/config/workspace/.agent-roadmap-sync/locks.yaml` in this item.

**Test Strategy**

No new test source. Verify exact dirty-path preservation, no unmerged entries, commit ancestry, and non-roadmap tree equivalence between the staging promotion commit and canonical result.

**Verification**

```bash
git -C /config/workspace/iop status -sb
git -C /config/workspace/iop diff --name-only | LC_ALL=C sort
git -C /config/workspace/iop diff --check
git -C /config/workspace/iop diff --name-only --diff-filter=U
```

Expected: canonical is on `dev`; only intentional post-apply evidence edits may be dirty; `diff --check` passes; no unmerged path is printed.

### [REFACTOR-2] Prove canonical closure readiness and reconcile Agent UI

**Problem**

The current staging Agent UI state at `agent-ui/.sync-state.json:21-49` still has pending milestone work for `component:console-shell`, and `agent-ui/definition/components/console-shell/index.md:4,24` remains `계획`. The pending entry may be reconciled only after canonical code and required Flutter verification pass. The parent lock must remain disabled until final archive.

**Solution**

Run the full canonical regression matrix on fresh output. Execute `complete-milestone` in check-only mode in `/config/workspace/iop`; only a closure-ready result may trigger `sync-agent-ui mode=reconcile-milestone-completion`. Update both the component document and components index to `구현됨`, move the exact pending entry to reconciled milestone work with the actual verification evidence, validate Agent UI, and re-run check-only. Do not archive the milestone or enable the parent lock in this task.

Before:

```yaml
component_id: console-shell
status: 계획
```

After:

```yaml
component_id: console-shell
status: 구현됨
```

**Modified Files and Checklist**

- [ ] Reconcile `/config/workspace/iop/agent-ui/.sync-state.json` only after canonical Flutter tests/build pass.
- [ ] Update `/config/workspace/iop/agent-ui/definition/components/console-shell/index.md` status and decision history.
- [ ] Update `/config/workspace/iop/agent-ui/definition/components/index.md` summary status.
- [ ] Mirror those reconciled Agent UI bytes into `agent-ui/.sync-state.json`, `agent-ui/definition/components/console-shell/index.md`, and `agent-ui/definition/components/index.md` in this workspace.
- [ ] Confirm `/config/workspace/.agent-roadmap-sync/locks.yaml` still reports the canonical target as `disable` before the later archive run.

**Test Strategy**

No new test source. Existing Flutter shell tests and web build are the declared pending-work requirements. Full Go, Control Plane/Edge wire, reconnect, readability, forbidden-surface, and Agent UI structure checks prevent a promotion-only false positive.

**Verification**

```bash
mkdir -p /config/workspace/iop/.tmp
TMPDIR=/config/workspace/iop/.tmp GOTMPDIR=/config/workspace/iop/.tmp go test -count=1 ./...
make client-test
make client-build-web
make test-control-plane-edge-wire
make readability-audit
IOP_DEV_RECONNECT_BIND_TIMEOUT=60 scripts/dev/edge-node-reconnect-diagnostic.sh
```

Run from `/config/workspace/iop`. Expected: all commands exit 0; reconnect initial and reconnect cycles preserve Node-local/Edge-rendered payload equivalence and one terminal completion.

### [REFACTOR-3] Record exact promotion evidence without opening the lock

**Problem**

`HANDOFF.md:83-88` has no staging promotion commit, canonical commit, verification timestamp, or applied status. Without exact commit identities, SDD S05 evidence cannot distinguish a verified canonical apply from the staging checkout result.

**Solution**

After canonical verification and Agent UI reconciliation, update `HANDOFF.md` in canonical and this workspace with actual 40-hex commit identities, `canonical_promotion: applied`, UTC verification time, canonical identity, and the still-disabled downstream lock result. Update the prose status at `HANDOFF.md:94-109` and evidence sequence at `HANDOFF.md:140-145` so it describes completed D04 separation and pending final roadmap archive, not unfinished Tasks 10/13/14/15.

Before:

```yaml
canonical_promotion: pending
canonical_lock_identity: iop:agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md
canonical_lock_result: rely-on:chronos:chronos-architecture-ownership-boundary
```

After schema:

```yaml
canonical_promotion: applied
staging_promotion_commit: <actual 40-hex commit>
canonical_promotion_commit: <actual 40-hex commit>
canonical_promotion_verified_at: <actual UTC timestamp>
canonical_lock_identity: iop:agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md
canonical_lock_result: rely-on:chronos:chronos-architecture-ownership-boundary (disabled until final archive)
```

**Modified Files and Checklist**

- [ ] Update `/config/workspace/iop/HANDOFF.md` with actual canonical promotion evidence.
- [ ] Mirror the same promotion evidence into `HANDOFF.md` in this workspace.
- [ ] Preserve every Task 13-16 digest and receipt pointer already present.
- [ ] Leave milestone archive and lock enable to the subsequent `complete-milestone` run.

**Test Strategy**

No new test source. Validate commit existence, 40-hex formatting, ancestor relationships, receipt digests, and exact dependency-checker output.

**Verification**

```bash
git -C /config/workspace/iop rev-parse --verify HEAD^{commit}
git -C /config/workspace/iop-s1 rev-parse --verify HEAD^{commit}
rg -n '^canonical_promotion: applied$|^staging_promotion_commit: [0-9a-f]{40}$|^canonical_promotion_commit: [0-9a-f]{40}$|^canonical_promotion_verified_at: ' /config/workspace/iop/HANDOFF.md HANDOFF.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
```

Expected: both commit objects resolve; both handoff files contain exact promotion fields; dependency checker prints `rely-on:chronos:chronos-architecture-ownership-boundary`; the corresponding lock entry remains disabled.

### [REFACTOR-4] Run final guarded verification and retain rollback evidence

**Problem**

The next completion run must be able to distinguish closure-ready canonical state from partial promotion. A successful code test alone does not prove canonical roadmap reconciliation, UI state, lock ordering, or rollback preservation.

**Solution**

Capture all final command output in the review evidence. Require clean diff checks in both workspaces, no forbidden migration surface, no pending Agent UI entry for this milestone, canonical `[검토중]` with all five task ids checked, and the parent lock still disabled. Retain the `/tmp` patch and named stash locator in review evidence; do not drop the stash in this plan.

**Modified Files and Checklist**

- [ ] Fill `agent-task/m-iop-agent-chronos-extraction-decoupling/17+15,16_canonical_promotion_closure/CODE_REVIEW-cloud-G10.md` with actual outputs and recovery locators.
- [ ] Do not archive the milestone, delete recovery evidence, or enable the Chronos lock.

**Test Strategy**

No new test source. This item aggregates deterministic state, content, and regression oracles required for the later completion transaction.

**Verification**

Run the commands in Final Verification and require every stated result.

## Modified Files Summary

| File | Items |
|------|-------|
| `HANDOFF.md` | REFACTOR-3 |
| `agent-ui/.sync-state.json` | REFACTOR-2, REFACTOR-3 |
| `agent-ui/definition/components/console-shell/index.md` | REFACTOR-2, REFACTOR-3 |
| `agent-ui/definition/components/index.md` | REFACTOR-2, REFACTOR-3 |
| `agent-task/m-iop-agent-chronos-extraction-decoupling/17+15,16_canonical_promotion_closure/CODE_REVIEW-cloud-G10.md` | REFACTOR-4 |

## Final Verification

Run canonical runtime verification from `/config/workspace/iop`:

```bash
mkdir -p /config/workspace/iop/.tmp
TMPDIR=/config/workspace/iop/.tmp GOTMPDIR=/config/workspace/iop/.tmp go test -count=1 ./...
make client-test
make client-build-web
make test-control-plane-edge-wire
make readability-audit
IOP_DEV_RECONNECT_BIND_TIMEOUT=60 scripts/dev/edge-node-reconnect-diagnostic.sh
git diff --check
```

Expected: every command exits 0 with fresh Go execution; Flutter tests/build, real Control Plane/Edge wire, readability ratchet, and initial/reconnect diagnostic pass.

Run deterministic boundary and state checks from `/config/workspace/iop`:

```bash
if rg --sort path -n -i 'chronos|agent_bridge|iop-agent|iop_agent|IopAgent|agentruntime|agentprovider|agenttask|agentworkspace' apps packages/go cmd proto configs; then exit 1; fi
test ! -d apps/agent
test -z "$(find packages/go -maxdepth 1 -type d -name 'agent*' -print -quit)"
test -z "$(git diff --name-only --diff-filter=U)"
rg -n '^status: 구현됨$|^Status: `구현됨`$' agent-ui/definition/components/console-shell/index.md
jq -e '.pending_milestone_work | length == 0' agent-ui/.sync-state.json
jq -e '.reconciled_milestone_work | any(.milestone_path == "agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md" and .state == "reconciled")' agent-ui/.sync-state.json
rg -n '^canonical_promotion: applied$|^staging_promotion_commit: [0-9a-f]{40}$|^canonical_promotion_commit: [0-9a-f]{40}$' HANDOFF.md
git diff --check
```

Expected: forbidden runtime surfaces and old package roots are absent; no unmerged entry exists; console shell and sync state are reconciled; promotion evidence is exact; diff check passes.

Run cross-workspace lock and preservation checks from `/config/workspace/iop-s1`:

```bash
git diff --check
rg -n '^canonical_promotion: applied$|^staging_promotion_commit: [0-9a-f]{40}$|^canonical_promotion_commit: [0-9a-f]{40}$' HANDOFF.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: local evidence matches canonical evidence; dependency checker prints `rely-on:chronos:chronos-architecture-ownership-boundary`; its `rely-on` status is still `disable`. Record the retained canonical roadmap patch path, SHA-256, and named stash locator in `CODE_REVIEW-cloud-G10.md`.

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