<!-- task=m-node-provider-execution-liveness-recovery/06+05_failure_wire_mapping plan=0 tag=API milestone-task=failure-handoff -->

# Normalized and Tunnel Failure Mapping

## For the Implementing Agent

Implement only this mapper child after its predecessor PASS, run every verification command, and fill all implementation-owned sections of `CODE_REVIEW-cloud-G08.md` with actual notes and raw command output. Keep active files in place and report ready for review; finalization belongs to the code-review skill. If blocked, record exact blocker evidence, attempted commands/output, and resume conditions only. 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

The additive protobuf contract is useful only when normalized and tunnel terminals preserve the same allowlisted liveness semantics. S04 requires Node to populate that contract without leaking raw provider output or inventing the Edge-owned recovery decision.

## Analysis

### Files Read

- `apps/node/internal/node/runtime_bridge.go`, `apps/node/internal/node/runtime_bridge_test.go`
- `apps/node/internal/node/liveness_watchdog.go`, `apps/node/internal/node/liveness_health_evidence.go`, `apps/node/internal/node/liveness_health_evidence_test.go`, `apps/node/internal/node/provider_tunnel_liveness_test.go`
- `apps/edge/internal/transport/server.go`, `apps/edge/internal/transport/connection_handlers.go`, `apps/edge/internal/transport/server_test.go`
- `agent-contract/inner/execution-runtime.md`, `agent-contract/inner/edge-node-runtime-wire.md`, `agent-spec/runtime/edge-node-execution.md`
- `agent-test/local/node-smoke.md`, `agent-test/local/edge-smoke.md`, `scripts/e2e-smoke.sh`, `scripts/e2e-openai-vllm.sh`

### SDD Criteria

- SDD: `agent-roadmap/sdd/operational-observability-provider-management/node-provider-execution-liveness-recovery/SDD.md`; status `[승인됨]`; `milestone-task=failure-handoff`.
- S04/Evidence Map S04 requires equal stable code/health/idle/attempt/fence/sequence meaning on both wire paths, no raw content, and no Node `recovery_eligible`. The checklist and round-trip fixtures are derived directly from that row.

### Verification Context

- `05+04_failure_wire_contract` supplies the optional generated fields and must PASS first. Focused conversion tests, package/race/vet checks, and repository-native normalized/fake-provider full cycles are local deterministic evidence.

### Test Coverage Gaps

- Current normalized conversion flattens `Failure.Message`; tunnel conversion carries error/metadata without typed code/retryability. No present/absent round-trip covers both paths.

### Symbol References

- No symbol is renamed or removed. One internal clone-safe mapper is added and every non-stall failure retains legacy string behavior.

### Split Judgment

- This consumer child depends only on the stable optional wire fields. It must PASS before Edge reception fencing can trust typed terminal semantics.

### Scope Rationale

Do not validate receiving connection identity, mutate provider health, release Edge leases, select candidates, or dispatch recovery.

### Final Routing

- `evaluation_mode=isolated-reassessment`; finalizer=`finalize-task-policy.sh pair`.
- Build closure true, scores `(2,1,2,1,2)`, grade G08, route `local-fit` -> `PLAN-local-G08.md`.
- Review closure true, scores `(2,1,2,1,2)`, grade G08, route `official-review` -> `CODE_REVIEW-cloud-G08.md` (`codex`, `gpt-5.6-sol`, `xhigh`).
- `large_indivisible_context=false`; positive loop risks: `boundary_contract`, `variant_product` (2). `review_rework_count=0`, `evidence_integrity_failure=false`.

## Implementation Checklist

- [ ] API-1 maps only allowlisted `response_stalled` failures on normalized and tunnel terminals while preserving legacy behavior for nil/other failures.
- [ ] Add absent/present, two-path parity, defensive-clone, and raw-free round-trip tests; synchronize runtime/wire contracts and living spec.
- [ ] Run focused, package, race, vet, provider-only/fake-provider full-cycle, and diff verification with fresh output.
- [ ] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

### [API-1] Preserve typed failures across both Node paths

**Problem:** normalized conversion emits only `Failure.Message`, while tunnel conversion copies error/metadata without the typed code and retryability hint.

**Solution:** Add one clone-safe mapper used by both conversions. Populate the optional wire failure only for `FailureCodeResponseStalled`, retain only the SDD allowlist, omit `recovery_eligible` and arbitrary metadata, and preserve legacy error strings for nil/other failures.

**Modified Files and Checklist:**

- [ ] `apps/node/internal/node/runtime_bridge.go`: map allowlisted stalled failures for normalized events.
- [ ] `apps/node/internal/node/liveness_watchdog.go`: attach the same failure to stalled tunnel frames/conversion.
- [ ] `apps/node/internal/node/runtime_bridge_test.go`: cover present/absent normalized conversion and defensive cloning.
- [ ] `apps/node/internal/node/liveness_health_evidence_test.go`: cover normalized/tunnel semantic parity and raw-free metadata.
- [ ] `apps/edge/internal/transport/server_test.go`: cover protobuf parser round-trips and unchanged message separation.
- [ ] `agent-contract/inner/execution-runtime.md`: document typed failure ownership and legacy compatibility.
- [ ] `agent-contract/inner/edge-node-runtime-wire.md`: document optional fields and safe metadata boundary.
- [ ] `agent-spec/runtime/edge-node-execution.md`: reflect the implemented two-path envelope.

**Test Strategy:** Assert nil and non-stall failures leave the field absent; stalled failures preserve code/retryable and allowlisted metadata across both paths while raw message/body/prompt/credential/arbitrary metadata and `recovery_eligible` remain absent.

**Verification:** focused Node and Edge parser tests must execute every new named fixture.

## Dependencies and Execution Order

1. `05+04_failure_wire_contract` must produce `agent-task/m-node-provider-execution-liveness-recovery/05+04_failure_wire_contract/complete.log`.
2. This child must PASS before `07+06_reception_fence` starts.

## Modified Files Summary

| File | Item |
|------|------|
| `apps/node/internal/node/runtime_bridge.go` | API-1 |
| `apps/node/internal/node/liveness_watchdog.go` | API-1 |
| `apps/node/internal/node/runtime_bridge_test.go` | API-1 |
| `apps/node/internal/node/liveness_health_evidence_test.go` | API-1 |
| `apps/edge/internal/transport/server_test.go` | API-1 |
| `agent-contract/inner/execution-runtime.md` | API-1 |
| `agent-contract/inner/edge-node-runtime-wire.md` | API-1 |
| `agent-spec/runtime/edge-node-execution.md` | API-1 |
| `agent-task/m-node-provider-execution-liveness-recovery/06+05_failure_wire_mapping/CODE_REVIEW-cloud-G08.md` | API-1 |

## Final Verification

Fresh Go output is required.

1. `go test -count=1 ./apps/node/internal/node -run '^(TestRuntimeEventToProtoPreservesTypedFailure|TestStallMetadata.*)$' && go test -count=1 ./apps/edge/internal/transport -run '^(TestEdgeParserMap_.*)$'` — PASS and all named new tests execute.
2. `go test -count=1 ./packages/go/execution ./apps/node/... ./apps/edge/internal/transport ./apps/control-plane/...` — PASS.
3. `go test -race -count=1 ./packages/go/execution ./apps/node/internal/node ./apps/edge/internal/transport` — PASS with no race report.
4. `go vet ./packages/go/execution ./apps/node/... ./apps/edge/internal/transport ./apps/control-plane/...` — no diagnostics.
5. `./scripts/e2e-smoke.sh` — PASS for normalized execution after typed mapping.
6. `IOP_VLLM_MODE=fake ./scripts/e2e-openai-vllm.sh` — PASS for credential-free Edge -> Node -> provider full-cycle.
7. `git diff --check` — no whitespace errors.

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