<!-- task=m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle plan=0 tag=REFACTOR -->

# Repository-neutral Chronos acceptance bundle 생성

## For the Implementing Agent

`CODE_REVIEW-cloud-G10.md`의 implementation-owned 섹션 작성은 필수다. 선행 task의 exact `complete.log`를 확인한 뒤 구현하고, 모든 검증의 실제 stdout/stderr를 기록한 채 활성 파일을 유지하고 review 준비 완료를 보고한다. 최종 판정·archive·`complete.log`는 code-review agent만 수행한다. 외부 state runner가 없으면 사용자에게 묻거나 우회하지 말고 preflight와 blocker, 재개 조건만 evidence 필드에 남긴다.

## Background

S02는 source, contract, behavior fixture와 기존 등록·설정·저장 상태 전체를 하나의 versioned acceptance bundle로 전달하되 이 IOP Milestone이 Chronos repository나 최종 source layout을 수정하지 않도록 요구한다. bundle은 실제 device path와 credential을 tracked artifact에 노출하지 않고, 격리 staging에서 live IOP checkout 없이 build/test 가능한 검증 baseline과 item digest를 제공해야 한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-chronos-extraction-decoupling.md)
- Task ids:
  - `transfer`: 전체 source/contract/behavior/state의 versioned Chronos acceptance bundle 전달
- Completion mode: check-on-pass

## Analysis

### Files Read

- `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-contract/inner/iop-agent-cli-runtime.md`
- `agent-contract/inner/agent-runtime.md`
- `configs/iop-agent.local.example.yaml`
- `packages/go/agentconfig/runtime_config.go`
- `packages/go/agentstate/store.go`
- `apps/agent/internal/taskloop/module.go`
- `apps/agent/internal/bootstrap/module.go`
- `apps/agent/internal/localcontrol/server.go`
- `apps/agent/internal/localcontrol/ledger.go`
- `Makefile`
- `agent-test/local/rules.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-test/local/testing-smoke.md`

### SDD Criteria

- SDD 상태 `[승인됨]`, 잠금 `해제`; target S02 / Task `transfer`.
- Evidence Map: 격리 staging build, existing behavior tests, bundle 외부 IOP dependency scan, 전체 state fixture, item/bundle digest.
- D01: 등록·설정·저장 상태와 깨진 잔여 기록도 읽기 전용 입력으로 전달하되 깨진 기록은 재개 가능으로 표시하지 않는다.
- 이 기준 때문에 source payload, verification snapshot, private state payload, contract/docs, provenance를 분리하고 real state export 없이는 PASS할 수 없다.

### Verification Context

- Handoff 없음. predecessor manifest는 아직 완료되지 않았고 `01_inventory/complete.log`가 missing이다.
- Local rules state는 usable. repository-native Go unit/build는 credential이 필요 없고 fresh `-count=1`을 사용한다.
- External Verification Preflight:
  - runner/workdir: 실제 `iop-agent` state를 소유한 host의 fixed IOP checkout; 현재 세션에서는 확인되지 않음.
  - source: branch/HEAD가 `3155be0e...`이고 code asset dirty drift가 없어야 함.
  - inputs: owner-readable local config와 state/overlay/log/temp/cache roots; 값이나 credential은 stdout/tracked task artifact에 출력하지 않음.
  - process: local-control socket/daemon writer가 정지되어 coherent snapshot을 보장해야 함.
  - output: repository 밖 owner-only directory, archive mode `0600`; Chronos repo는 output 대상이 아님.
  - blocker: runner, config, state roots 또는 quiesced ownership을 증명할 수 없으면 synthetic fixture까지만 실행하고 external-execution blocker로 남긴다.
- Confidence: high for tool/schema/staging fixture, medium for real state evidence until external preflight is supplied.

### Test Coverage Gaps

- Existing behavior tests cover source semantics but not bundle assembly, path traversal, symlink, output confinement, digest reproducibility, broken-state quarantine; `main_test.go`에 정상/경계/오류 test를 추가한다.
- Real state completeness는 synthetic fixture만으로 대체할 수 없으므로 external runner evidence가 필수다.

### Symbol References

- New command only: `cmd/iop-chronos-transfer`.
- Existing runtime symbols are copied as payload and are not renamed in this task.

### Split Judgment

- Child stable contract: inventory manifest를 입력으로 repository-neutral v1 bundle과 redacted receipt를 생성하고 격리 staging 검증을 통과한다.
- Predecessor `01`: active/archived `complete.log` missing. 구현 시작 전 동일 task group의 exact `01_inventory/complete.log` 또는 archived exact completion log가 하나 존재해야 한다.
- PASS evidence: synthetic + real-state bundle manifest/digest, extracted build/test, no external dependency, redacted task logs.
- `03+02_decouple`는 이 PASS 전 삭제를 시작할 수 없다.

### Scope Rationale

- Chronos repository import, final package layout, state activation/write는 downstream 잠금 뒤 책임이라 제외한다.
- 실제 state payload와 device paths는 repository와 `agent-task`에 저장하지 않는다.
- IOP source 삭제는 이 plan에서 하지 않는다.

### Final Routing

- `evaluation_mode=first-pass`, finalizer=`finalize-task-policy.sh`, mode=`pair`.
- Build closures 모두 true. Scores=`2,2,2,2,2`, grade=`G10`, base/route=`grade-boundary`, lane=`cloud`.
- Review scores=`2,2,2,2,2`, route=`official-review`, lane=`cloud`, grade=`G10`.
- `large_indivisible_context=false`; loop risks=`temporal_state, concurrent_consistency, boundary_contract, structured_interpretation` (4); `review_rework_count=0`; `evidence_integrity_failure=false`; capability gap 없음.
- Canonical files: `PLAN-cloud-G10.md`, `CODE_REVIEW-cloud-G10.md`.

## Dependencies and Execution Order

1. `01_inventory` must have exactly one matching active or archived `complete.log`; it is currently missing.
2. Read only that exact predecessor completion evidence and the stable `scripts/fixtures/iop-agent-chronos-ownership-manifest.tsv`.
3. Build and verify the bundle before any source deletion.

## Implementation Checklist

- [ ] Refuse to start until predecessor `01_inventory` has an exact PASS `complete.log` and the manifest passes its schema/completeness checks.
- [ ] Implement the Go export command with repository-neutral v1 layout, deterministic item digests, external-output confinement, quiesced real-state export, and broken-record quarantine.
- [ ] Add sanitized schema/fixture coverage for complete state categories, malformed residual records, path traversal, symlink, duplicate path, and reproducible digest behavior.
- [ ] Generate source-only synthetic and real-state private bundles, extract to isolated staging, and prove build/tests and bundle-external dependency scan pass without invoking `iop-agent`.
- [ ] Record only redacted manifest/digest/preflight evidence in task logs; if the user-owned runner is unavailable, record the external-execution blocker and do not claim PASS.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REFACTOR-1] Versioned bundle exporter와 안전 경계

**Problem**

`SDD.md:59-70`은 bundle과 전체 legacy state export를 요구하지만 현재 deterministic exporter, output confinement, redaction contract가 없다.

```text
# agent-roadmap/sdd/.../SDD.md:59-60
chronos_transfer_bundle
legacy_state_export
```

**Solution**

stdlib-only Go command를 추가한다. manifest의 transfer/retain/reference payload를 immutable source snapshot으로 복사하고 `acceptance-v1/{source,state,contracts,behavior,provenance}`를 만든다. output은 workspace와 Chronos checkout 밖의 absolute owner-only root만 허용한다. real state mode는 quiesced socket/process evidence, root ownership, symlink/path traversal를 검증하고 broken records를 `state/quarantine`에 원문 보존하되 `resumable=false`로 표시한다.

```text
# after: cmd/iop-chronos-transfer/main.go
iop-chronos-transfer export --manifest <tsv> --source-revision <sha> \
  --repo-root <iop> --local-config <owner-file> --state-root <owner-root> \
  --output <outside-repo-owner-only-dir>
```

**Modified Files and Checklist**

- [ ] `cmd/iop-chronos-transfer/main.go` — CLI parsing, validation, deterministic archive/digest, redacted receipt.
- [ ] `cmd/iop-chronos-transfer/main_test.go` — safe output, path/symlink rejection, deterministic digest, state quarantine tests.

**Test Strategy**

- `TestExportSyntheticBundle`, `TestRejectsOutputInsideWorkspace`, `TestRejectsTraversalAndSymlink`, `TestDigestStableAcrossRuns`, `TestBrokenStateIsQuarantinedNotResumable`, `TestRefusesLiveStateSocket`를 작성한다.

**Verification**

- `go test -count=1 ./cmd/iop-chronos-transfer` — all tests PASS; cache 불허.
- `go vet ./cmd/iop-chronos-transfer` — findings 0.

### [REFACTOR-2] State schema와 sanitized full-category fixture

**Problem**

실제 state를 tracked fixture로 복사할 수 없고, config/state/client/log/overlay/cache/temp 및 broken residual을 모두 포함한다는 검증 가능한 schema가 없다.

```yaml
# configs/iop-agent.local.example.yaml:5-10
device:
  state_root: ...
  overlay_root: ...
  log_root: ...
  temp_root: ...
  cache_root: ...
```

**Solution**

schema는 category, source_revision, digest, size, mode, resumable, quarantine_reason을 정의하고 실제 host path와 credentials를 금지한다. synthetic fixture는 모든 category와 valid/broken records를 가짜 값으로 포함한다.

```json
// after: scripts/fixtures/iop-agent-chronos-transfer-state-v1.json
{"version":1,"records":[{"category":"checkpoint","resumable":true},{"category":"quarantine","resumable":false}]}
```

**Modified Files and Checklist**

- [ ] `scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json` — state/provenance schema와 sensitive-field 금지.
- [ ] `scripts/fixtures/iop-agent-chronos-transfer-state-v1.json` — sanitized full-category fixture.

**Test Strategy**

- Go tests가 schema-required fields, all categories, broken record quarantine, path/secret redaction을 검증한다.

**Verification**

- `jq -e . scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json scripts/fixtures/iop-agent-chronos-transfer-state-v1.json >/dev/null` — valid JSON.
- `! rg -n '/home/|/Users/|token|credential|secret|private_key' scripts/fixtures/iop-agent-chronos-transfer-state-v1.json` — sensitive values 없음.

### [REFACTOR-3] 격리 staging build와 실제 state export evidence

**Problem**

bundle이 source를 담았다는 사실만으로는 live IOP checkout 없이 build 가능하거나 실제 state가 완전하게 전달됐음을 증명하지 못한다.

```text
# SDD.md:127-130
격리 staging build + 전체 state 형식 + item/bundle digest
```

**Solution**

synthetic export를 `/tmp/iop-chronos-transfer-fixture`에 만들고 다른 `/tmp` staging root에 풀어 bundled verification snapshot의 fresh tests를 실행한다. 실제 runner에서는 동일 command를 owner-only external output에 실행하고 task log에는 source revision, category counts, redacted item digest, bundle digest, mode만 기록한다.

```text
# after: transfer-bundle-manifest.log
version=1 source_revision=<sha> item_count=<n> state_categories=<redacted counts> bundle_sha256=<digest>
```

**Modified Files and Checklist**

- [ ] `agent-task/m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle/transfer-bundle-manifest.log` — path/secret 없는 receipt summary.
- [ ] `agent-task/m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle/transfer-verification.log` — exact preflight, commands, stdout/stderr.
- [ ] `agent-task/m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle/CODE_REVIEW-cloud-G10.md` — actual implementation/review evidence.

**Test Strategy**

- synthetic bundle은 local required verification이다.
- real state bundle은 external-execution required verification이며 미실행 시 blocker다. `iop-agent` binary는 실행하지 않는다.

**Verification**

- `rm -rf /tmp/iop-chronos-transfer-fixture /tmp/iop-chronos-transfer-staging && go run ./cmd/iop-chronos-transfer export --manifest scripts/fixtures/iop-agent-chronos-ownership-manifest.tsv --source-revision 3155be0e275437a8eedc1aa93497955a7d30465b --repo-root . --state-fixture scripts/fixtures/iop-agent-chronos-transfer-state-v1.json --output /tmp/iop-chronos-transfer-fixture && mkdir -p /tmp/iop-chronos-transfer-staging && tar -xzf /tmp/iop-chronos-transfer-fixture/chronos-acceptance-v1.tar.gz -C /tmp/iop-chronos-transfer-staging` — synthetic export/extract PASS.
- `cd /tmp/iop-chronos-transfer-staging/acceptance-v1/behavior && go test -count=1 ./...` — bundled behavior tests PASS without current checkout.
- `test -z "$(rg --sort path -n '/config/workspace/iop|replace .*iop|\.\./.*iop' /tmp/iop-chronos-transfer-staging/acceptance-v1)"` — bundle-external IOP source dependency 0.
- External runner command with real `--local-config`, `--state-root`, `--output` must exit 0 and produce mode `0600`; exact non-secret command/output goes to `transfer-verification.log`.

## Modified Files Summary

| File | Item |
|------|------|
| `cmd/iop-chronos-transfer/main.go` | REFACTOR-1 |
| `cmd/iop-chronos-transfer/main_test.go` | REFACTOR-1 |
| `scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json` | REFACTOR-2 |
| `scripts/fixtures/iop-agent-chronos-transfer-state-v1.json` | REFACTOR-2 |
| `agent-task/m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle/transfer-bundle-manifest.log` | REFACTOR-3 |
| `agent-task/m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle/transfer-verification.log` | REFACTOR-3 |
| `agent-task/m-iop-agent-chronos-extraction-decoupling/02+01_transfer_bundle/CODE_REVIEW-cloud-G10.md` | REFACTOR-3 |

## Final Verification

1. Confirm the exact predecessor `01_inventory/complete.log` and rerun its manifest checks.
2. `go test -count=1 ./cmd/iop-chronos-transfer`
3. `go vet ./cmd/iop-chronos-transfer`
4. `jq -e . scripts/fixtures/iop-agent-chronos-transfer-state-v1.schema.json scripts/fixtures/iop-agent-chronos-transfer-state-v1.json >/dev/null`
5. `! rg -n '/home/|/Users/|token|credential|secret|private_key' scripts/fixtures/iop-agent-chronos-transfer-state-v1.json`
6. Run the exact synthetic export/extract command in REFACTOR-3, then `cd /tmp/iop-chronos-transfer-staging/acceptance-v1/behavior && go test -count=1 ./...`.
7. `test -z "$(rg --sort path -n '/config/workspace/iop|replace .*iop|\.\./.*iop' /tmp/iop-chronos-transfer-staging/acceptance-v1)"`
8. Run and record the real-state external preflight/export. Require source revision match, no live writer, owner-only inputs/output, archive mode `0600`, complete category counts, quarantined broken records with `resumable=false`, and matching item/bundle digests. Synthetic evidence cannot replace this step.

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