<!-- task=m-iop-agent-cli-runtime/08+06,07_quota_failure plan=3 tag=REVIEW_TEST -->

# Complete the Quota Projection Integrity Evidence Matrix

## For the Implementing Agent

Run every verification command and fill the implementation-owned sections of `CODE_REVIEW-*-G??.md` with actual notes and stdout/stderr. Keep the active pair in place and report ready for review; only the code-review skill may append a verdict, archive files, write `complete.log`, or classify the next state. If blocked, record the exact blocker, attempted command/output, and resume condition in implementation-owned evidence fields; do not ask the user, call user-input tools, create control-plane stop files, or classify the next state.

## Background

The projection seal implementation and every fresh reviewer command pass, but the required evidence matrix does not exercise every sealed identity field. This follow-up adds only the missing snapshot-ID, adapter, and `not_applicable` cases so S07 completion evidence matches the approved plan and contract.

## Archive Evidence Snapshot

- Prior plan: `agent-task/m-iop-agent-cli-runtime/08+06,07_quota_failure/plan_cloud_G08_2.log`
- Prior review: `agent-task/m-iop-agent-cli-runtime/08+06,07_quota_failure/code_review_cloud_G08_2.log`
- Verdict: `FAIL`
- Findings: 1 Required, 0 Suggested, 0 Nit.
- Required summary:
  - Complete the projection-integrity regression matrix with snapshot-ID and adapter mutation in policy, JSON, and manager paths, add the required `not_applicable` JSON round trip, and assert full canonical corrupt persistence.
- Affected files: `packages/go/agentpolicy/failure_policy_test.go`, `packages/go/agenttask/failure_continuation_test.go`, and the active review evidence.
- Reviewer verification:
  - Focused sanitizer/JSON, manager/store, and raw-snapshot suites passed.
  - Affected package suites, race suites, `go vet ./packages/go/...`, `go test -count=1 ./packages/go/...`, formatting, deterministic searches, and `git diff --check` passed.
  - Production code and both runtime contracts already cover the omitted fields; no production or contract change is justified unless a new regression fails.
- Routing signals: `review_rework_count=3`, `evidence_integrity_failure=false`.
- Roadmap carryover: S07 / `quota-failure` remains incomplete; the Milestone was not modified.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md`
- Milestone link: [Milestone document](agent-roadmap/phase/automation-runtime-bridge/milestones/iop-agent-cli-runtime.md)
- Task ids:
  - `quota-failure`: typed quota/failure and policy-only retry/failover
- Completion mode: check-on-pass

## Analysis

### Files Read

- `packages/go/agentpolicy/quota.go`
- `packages/go/agentpolicy/failure_policy.go`
- `packages/go/agentpolicy/failure_policy_test.go`
- `packages/go/agenttask/dispatch.go`
- `packages/go/agenttask/failure_continuation_test.go`
- `agent-contract/index.md`
- `agent-contract/inner/agent-runtime.md`
- `agent-contract/inner/iop-agent-cli-runtime.md`
- `agent-spec/index.md`
- `agent-spec/runtime/edge-node-execution.md`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `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-test/local/rules.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-task/m-iop-agent-cli-runtime/08+06,07_quota_failure/plan_cloud_G08_2.log`
- `agent-task/m-iop-agent-cli-runtime/08+06,07_quota_failure/code_review_cloud_G08_2.log`
- `agent-task/archive/2026/07/m-iop-agent-cli-runtime/06+05_config_registry/complete.log`
- `agent-task/archive/2026/07/m-iop-agent-cli-runtime/07+06_target_policy/complete.log`

### SDD Criteria

- SDD: `agent-roadmap/sdd/automation-runtime-bridge/iop-agent-cli-runtime/SDD.md`; status `[승인됨]`, lock `해제`.
- Target: S07 / `quota-failure`.
- Acceptance: typed evidence and immutable quota snapshots remain isolated, continuation occurs only through declared policy, and unknown evidence blocks the work unit.
- Evidence Map: quota parser, runtime observation, isolation, and failover tests; PASS must provide snapshot/failure transition evidence in `Roadmap Completion`.
- The missing identity and `not_applicable` cases are therefore completion evidence, not optional test style.

### Test Environment Rules

- `test_env=local`.
- Read `agent-test/local/rules.md` and `agent-test/local/platform-common-smoke.md`.
- Apply Go preflight, focused fresh tests, affected package tests, race tests for manager state transitions, `go vet ./packages/go/...`, the full shared-package suite, formatting, deterministic search, and `git diff --check`.
- No external service, credential, E2E, or full-cycle invocation is required because this follow-up changes only deterministic package tests.

### Test Coverage Gaps

- `TestSanitizeQuotaObservationRejectsProjectionTampering` covers state, target, checked time, validity, and reason drift, but not snapshot-ID or adapter drift.
- `TestQuotaObservationJSONRoundTripRejectsTampering` covers state, target, checked time, validity, reason, seal, and unknown-field drift, but not snapshot-ID or adapter drift; its round-trip set omits `not_applicable`.
- `TestFailureContinuationProjectionTamperBecomesTypedBlocker` covers state, target, checked time, validity, and reason drift, but not snapshot-ID or adapter drift, and it checks only corrupt validity rather than the complete canonical corrupt value.
- Existing production behavior covers the missing cases through the same seal comparison; the follow-up must prove that fact without changing production code.

### Symbol References

- None. No production symbol is renamed, removed, or added.

### Split Judgment

- Keep one compact test-only plan: policy sanitizer/JSON and manager persistence are the two required observations of one projection-integrity evidence invariant.
- Predecessor `06` is satisfied by `agent-task/archive/2026/07/m-iop-agent-cli-runtime/06+05_config_registry/complete.log`.
- Predecessor `07` is satisfied by `agent-task/archive/2026/07/m-iop-agent-cli-runtime/07+06_target_policy/complete.log`.

### Scope Rationale

- Include only the two existing regression files and active review evidence.
- Exclude production seal/JSON/manager/store code, runtime contracts, raw quota snapshot logic, selection policy, scheduler timing, and other S07/S08/S09 work unless a newly added required regression fails.
- Do not add a new test name; extend the existing named matrices so the plan's focused commands remain stable.

### Final Routing

- `evaluation_mode=isolated-reassessment`; `finalizer=finalize-task-policy.sh`, mode `pair`.
- Build and review closures are all true: scope, context, verification, evidence, ownership, and decisions are closed; no capability gap exists.
- Build scores: scope=1, state=1, blast=0, evidence=1, verification=1; grade `G04`, base basis `local-fit`.
- `large_indivisible_context=false`; positive loop risk: `variant_product`; count=1.
- Recovery signals: `review_rework_count=3`, `evidence_integrity_failure=false`; recovery boundary matched.
- Build route: `recovery-boundary`, cloud `G04`, filename `PLAN-cloud-G04.md`.
- Review scores: scope=1, state=1, blast=0, evidence=1, verification=1; route `official-review`, cloud `G04`, Codex `gpt-5.6-sol` xhigh, filename `CODE_REVIEW-cloud-G04.md`.

## Implementation Checklist

- [ ] Complete the policy sanitizer and strict JSON matrices with snapshot-ID and adapter drift plus valid, stale, not-applicable, and corrupt round trips.
- [ ] Complete the manager mutation matrix with snapshot-ID and adapter drift, full canonical corrupt persistence, and exactly one invocation per case.
- [ ] Run focused, affected, race, vet, full shared-package, formatting, deterministic search, and diff verification without production or contract changes.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [REVIEW_TEST-1] Complete policy and JSON projection cases

**Problem:** `packages/go/agentpolicy/failure_policy_test.go:121` omits `SnapshotID` and `Adapter` from the in-memory drift table. The JSON drift table at line 204 omits the same fields, and the round-trip set at line 184 uses unknown instead of the plan-required `not_applicable` case.

**Solution:** Extend the existing tables with independent snapshot-ID and adapter mutations. Add a normalized `QuotaStateNotApplicable` observation to the round-trip set while retaining useful existing cases. Keep the expected result canonical corrupt for sanitizer drift and strict decode failure for serialized drift.

Before (`packages/go/agentpolicy/failure_policy_test.go:127`):

```go
{
    name:        "state",
    observation: policyQuotaObservation("ignored", QuotaStateAvailable),
    mutate: func(observation *QuotaObservation) {
        observation.State = QuotaStateExhausted
    },
},
```

After:

```go
{
    name:        "snapshot ID",
    observation: policyQuotaObservation("ignored", QuotaStateAvailable),
    mutate: func(observation *QuotaObservation) {
        observation.SnapshotID = "quota-" + strings.Repeat("0", 64)
    },
},
{
    name:        "adapter identity",
    observation: policyQuotaObservation("ignored", QuotaStateAvailable),
    mutate: func(observation *QuotaObservation) {
        observation.Adapter = "other-provider"
    },
},
```

Use a syntactically valid but different snapshot ID in the actual test so failure proves seal drift rather than shape rejection.

**Modified Files and Checklist:**

- [ ] `packages/go/agentpolicy/failure_policy_test.go`: add snapshot-ID/adapter sanitizer and JSON drift cases and the `not_applicable` round trip.

**Test Strategy:** Extend `TestSanitizeQuotaObservationRejectsProjectionTampering` and `TestQuotaObservationJSONRoundTripRejectsTampering`. Assert each new drift becomes `CorruptQuotaObservation` or a strict JSON error; assert valid, stale, not-applicable, and corrupt observations round-trip without shared reason storage.

**Verification:**

```bash
go test -count=1 -run 'Test(SanitizeQuotaObservationRejectsProjectionTampering|QuotaObservationJSONRoundTripRejectsTampering)$' ./packages/go/agentpolicy
```

Expected: every sanitizer and strict JSON subtest passes.

### [REVIEW_TEST-2] Complete manager fail-closed identity cases

**Problem:** `packages/go/agenttask/failure_continuation_test.go:138` omits snapshot-ID and adapter drift, even though both fields are manager-visible and sealed. Its durable assertion at lines 218-220 checks only `Validity`, so it does not prove the complete canonical corrupt value was persisted.

**Solution:** Add independent snapshot-ID and adapter mutations to the existing manager table. Compare the persisted quota value with `agentpolicy.CorruptQuotaObservation()` and retain the exactly-one-invocation assertion for every case.

Before (`packages/go/agenttask/failure_continuation_test.go:218`):

```go
if len(work.AttemptObservations) != 1 ||
    work.AttemptObservations[0].Observation.Quota.Validity != agentpolicy.ObservationCorrupt {
    t.Fatalf("durable observations = %#v", work.AttemptObservations)
}
```

After:

```go
if len(work.AttemptObservations) != 1 ||
    !reflect.DeepEqual(
        work.AttemptObservations[0].Observation.Quota,
        agentpolicy.CorruptQuotaObservation(),
    ) {
    t.Fatalf("durable observations = %#v", work.AttemptObservations)
}
```

Add the standard-library `reflect` import. Use a syntactically valid but different snapshot ID so the manager regression proves seal drift.

**Modified Files and Checklist:**

- [ ] `packages/go/agenttask/failure_continuation_test.go`: add snapshot-ID/adapter mutation cases and exact canonical persistence assertion.
- [ ] `agent-task/m-iop-agent-cli-runtime/08+06,07_quota_failure/CODE_REVIEW-cloud-G04.md`: record actual implementation and complete verification output.

**Test Strategy:** Extend `TestFailureContinuationProjectionTamperBecomesTypedBlocker`. Every table case must end in `BlockerFailureObservationCorrupt`, persist exactly one canonical corrupt observation, and leave the provider invocation count at one.

**Verification:**

```bash
go test -count=1 -run '^TestFailureContinuationProjectionTamperBecomesTypedBlocker$' ./packages/go/agenttask
```

Expected: every manager identity and field mutation case passes.

## Modified Files Summary

| File | Item |
|---|---|
| `packages/go/agentpolicy/failure_policy_test.go` | REVIEW_TEST-1 |
| `packages/go/agenttask/failure_continuation_test.go` | REVIEW_TEST-2 |
| `agent-task/m-iop-agent-cli-runtime/08+06,07_quota_failure/CODE_REVIEW-cloud-G04.md` | REVIEW_TEST-2 |

## Final Verification

```bash
command -v go && go version && go env GOROOT
gofmt -d packages/go/agentpolicy/failure_policy_test.go packages/go/agenttask/failure_continuation_test.go
go test -count=1 -run 'Test(SanitizeQuotaObservationRejectsProjectionTampering|QuotaObservationJSONRoundTripRejectsTampering)$' ./packages/go/agentpolicy
go test -count=1 -run '^TestFailureContinuationProjectionTamperBecomesTypedBlocker$' ./packages/go/agenttask
go test -count=1 ./packages/go/agentpolicy ./packages/go/agenttask ./packages/go/agentstate
go test -count=1 -race ./packages/go/agentpolicy ./packages/go/agenttask ./packages/go/agentstate
go vet ./packages/go/...
go test -count=1 ./packages/go/...
rg --sort path -n 'snapshot ID|adapter identity|QuotaStateNotApplicable|CorruptQuotaObservation' packages/go/agentpolicy/failure_policy_test.go packages/go/agenttask/failure_continuation_test.go
if rg --sort path -n 'RawOutput' packages/go/agentpolicy packages/go/agenttask; then exit 1; else test $? -eq 1; fi
git diff --check
```

Expected: Go preflight resolves; formatting emits no diff; every focused, affected, race, vet, and shared-package command passes fresh; deterministic anchors show the complete evidence matrix; no `RawOutput` reference exists in durable policy/task packages; and the diff check is clean. Cached test output is not acceptable because every test command uses `-count=1`.

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