<!-- task=m-node-provider-execution-liveness-recovery/14+11,12,13_observability_contracts plan=0 tag=REFACTOR milestone-task=ops-evidence -->

# Code Review Reference - REFACTOR

> **[IMPLEMENTING AGENT — READ FIRST] Filling in this file is the mandatory final step of implementation.**
> The task is NOT complete until every implementation-owned section below is filled in.
> Complete the `Implementation Checklist`; the final checklist item is mandatory before saving.
> Fill implementation-owned sections, then stop with active files in place and report ready for review.
> Execute the plan's selected root cause, scope, files, and dependency decisions as written. Do not choose another owner, narrow/expand the write boundary, or replace a fix with another verification attempt.
> If implementation is blocked, record the exact blocker, attempted commands/output, and resume condition only in implementation-owned evidence fields.
> Do not ask the user directly, present choices, call user-input tools, create control-plane stop files, or classify the next state.
> Finalization (`Code Review Result`, log rename, `complete.log`, archive moves, `Review-Only Checklist`) is review-agent-only, even after compaction/resume.
> Follow the ownership table at the bottom of this file for which sections you own.

## Overview

date=2026-08-05
task=m-node-provider-execution-liveness-recovery/14+11,12,13_observability_contracts, plan=0, tag=REFACTOR

## Archive Evidence Snapshot

- Replaced pair evidence: `agent-task/m-node-provider-execution-liveness-recovery/11+06_node_liveness_observability/plan_local_G05_2.log` and `agent-task/m-node-provider-execution-liveness-recovery/11+06_node_liveness_observability/code_review_cloud_G05_2.log`; the pair was unimplemented and had no official verdict or verification output.
- Pre-refine intent at checkpoint `729f458a42f2c0c05fcb5d1c84738b41b41cd7cf`: the immediate prior pair set assigned `agent-contract/inner/execution-runtime.md`, `agent-contract/inner/edge-node-runtime-wire.md`, and `agent-spec/runtime/edge-node-execution.md` across children 11/12/13. Refinement removed overlap but did not create a replacement owner.
- Carryover: preserve disjoint implementation write sets and document only reviewed behavior. Do not copy planned claims into current contracts/specs before dependencies pass, and do not reopen the overlay-specific or OpenAI-specific documents that remain owned by children 12 and 13.

## For the Review Agent

> **[REVIEW AGENT ONLY]** The finalization steps below are review-agent only. Implementing agents must not execute this section.

Compare implementation of each item against source files and verify that output in `Verification Results` matches code.
Review completion means the following steps are finished:

1. Append verdict and `review_rework_count` / `evidence_integrity_failure` routing signals.
2. Archive `CODE_REVIEW-cloud-G05.md` → `code_review_cloud_G05_0.log` and `PLAN-local-G05.md` → `plan_local_G05_0.log`.
3. If PASS, write `complete.log` and move active task directory to `agent-task/archive/YYYY/MM/m-node-provider-execution-liveness-recovery/14+11,12,13_observability_contracts/`. If WARN/FAIL, fully write the next filesystem state required by the code-review skill.
4. If PASS and task group is `m-node-provider-execution-liveness-recovery`, preserve the first-line `milestone-task` metadata in `complete.log` and report it for the runtime aggregation event. Roadmap state evaluation belongs to `sync-milestone-workstate`.
5. Check applicable `Review-Only Checklist` items at the final `.log` location before reporting.

---

## Implementation Item Completion

| Item | Status |
|------|---------|
| REFACTOR-1 | [x] |
| REFACTOR-2 | [x] |

## Implementation Checklist

- [x] REFACTOR-1 synchronizes the shared execution and wire contracts with the reviewed Node stall, provider-health overlay, and recovery operational evidence, including owner, bounded label/log vocabulary, and the unchanged-wire boundary.
- [x] REFACTOR-2 synchronizes the living Edge/Node execution spec with the exact reviewed source symbols, behavior, tests, and deterministic S06 verification while removing superseded future-work claims only where implementation now exists.
- [x] Confirm all dependency gates, run every focused/package/document/diff command in Final Verification with fresh output, and verify the three-document write set is exact.
- [x] Fill implementation-owned sections in CODE_REVIEW-*-G??.md with actual implementation notes and verification output.

## Review-Only Checklist

> **[REVIEW AGENT ONLY]** This checklist is used only by the review agent.
> Implementing agents must not modify or check this section.

- [x] Append one verdict of `PASS`, `WARN`, or `FAIL` and verified `review_rework_count`, `evidence_integrity_failure` to `Code Review Result`.
- [x] Verify that verdict, `Dimension Assessment`, and Required/Suggested/Nit classifications match.
- [x] Archive active `CODE_REVIEW-*-G??.md` to `code_review_cloud_G05_0.log`.
- [x] Archive active `PLAN-*-G??.md` to `plan_local_G05_0.log`.
- [x] Verify that the Agent-Ops managed block in `.gitignore` unignores `agent-task/**/*.md` and `agent-task/**/*.log` and ignores `agent-roadmap/current.md`.
- [ ] If PASS, write `complete.log` based on `agent-ops/skills/common/code-review/templates/complete-log-template.md` and leave no active `.md` files.
- [ ] If PASS, move active task directory `agent-task/m-node-provider-execution-liveness-recovery/14+11,12,13_observability_contracts/` to `agent-task/archive/YYYY/MM/m-node-provider-execution-liveness-recovery/14+11,12,13_observability_contracts/` and update this checklist at the final archive path.
- [ ] If PASS and task group is `m-node-provider-execution-liveness-recovery`, preserve and report `milestone-task` metadata for runtime aggregation, without modifying roadmap or directly calling `update-roadmap`.
- [ ] If PASS for split work, remove empty active parent `agent-task/m-node-provider-execution-liveness-recovery/` or verify it was kept due to remaining siblings/files.
- [x] If WARN/FAIL, write the next filesystem state matching code-review verdict and do not write `complete.log`.

## Deviations from Plan

None. All three declared shared documents were updated exactly as specified. No Go code, tests, wire schema, metric exporters, roadmap, SDD, rules, or skills were modified.

## Key Design Decisions

- REFACTOR-1 was executed before REFACTOR-2 so the living spec could cite the finalized shared contract language.
- The execution contract operational-evidence section was added after the Health probe contract section and before Prohibited ownership, preserving the document's logical flow from runtime primitives → probe → evidence projections → ownership boundaries.
- The wire contract operational-projection boundary section was added after the 금지 사항 section and before 변경 시 확인할 코드/테스트, making the no-wire-widening statement a standalone section for visibility.
- The living spec change record was extended with a 2026-08-06 entry that documents the exact source files and test names for each producer, rather than duplicating contract detail owned by the provider-pool, configuration, streamgate, or OpenAI specs.
- Future-work claims in the spec's 한계와 주의사항 and 기능 목록 sections were replaced only where reviewed implementation now exists; remaining future-work statements for unproven behavior were preserved.

## Reviewer Checkpoints

- Verify all three declared dependency `complete.log` files exist, record PASS, and correspond to children 11, 12, and 13 before any shared document was edited.
- Verify every documented metric/event name, owner, bounded value, and exact-once/timing statement matches reviewed source and dependency completion evidence rather than the superseded plans.
- Verify the wire document explicitly states that operational projections do not add a frame, field, ordering rule, or retry semantic.
- Verify the execution contract distinguishes prohibited metric/general-log fields from valid request-scoped typed terminal metadata.
- Verify the living spec cites existing source symbols and non-zero-match deterministic tests for the Node, overlay, and recovery evidence matrix.
- Verify the diff changes only the three declared shared documents and this review stub; child 12/13 documents, code, tests, roadmap, SDD, rules, and skills remain untouched.

## Verification Results

Fill each output block with actual stdout/stderr. If a command changes, record the replacement and reason in `Deviations from Plan`.

### Verification 1

Command: `bash -O nullglob -c 'for index in 11 12 13; do matches=(agent-task/m-node-provider-execution-liveness-recovery/${index}_*/complete.log agent-task/m-node-provider-execution-liveness-recovery/${index}+*/complete.log agent-task/archive/*/*/m-node-provider-execution-liveness-recovery/${index}_*/complete.log agent-task/archive/*/*/m-node-provider-execution-liveness-recovery/${index}+*/complete.log); ((${#matches[@]} == 1)) || exit 1; done'`

Expected: PASS only when exactly one active or same-task-group archived completion exists for each predecessor index.

Output:
```
PASS
```

Dependency evidence:
- Index 11: `agent-task/archive/2026/08/m-node-provider-execution-liveness-recovery/11+06_node_liveness_observability/complete.log` (final verdict PASS, 4-fixture oracle, hostile values, panic-safe terminal delivery, numeric duration evidence)
- Index 12: `agent-task/archive/2026/08/m-node-provider-execution-liveness-recovery/12+08_health_overlay_observability/complete.log` (final verdict PASS, state-transition/snapshot/production recovery-path/verification evidence, complete forbidden-value scan)
- Index 13: `agent-task/archive/2026/08/m-node-provider-execution-liveness-recovery/13+10_recovery_observability/complete.log` (final verdict PASS, literal family-set and exact six-field lifecycle oracles)

### Verification 2

Command: `go test -count=1 ./packages/go/execution ./apps/node/internal/node ./apps/edge/internal/service ./packages/go/streamgate ./apps/edge/internal/openai`

Expected: PASS for all affected runtime packages.

Output:
```
ok  	iop/packages/go/execution	0.029s
ok  	iop/apps/node/internal/node	0.975s
ok  	iop/apps/edge/internal/service	6.040s
ok  	iop/packages/go/streamgate	0.915s
ok  	iop/apps/edge/internal/openai	7.567s
```

### Verification 3

Command: `go test -count=1 ./apps/node/internal/node -run '^TestNodeLivenessObservability' && go test -count=1 ./apps/edge/internal/service -run '^TestProviderHealthObservability' && go test -count=1 ./apps/edge/internal/openai -run '^(TestOpenAILivenessObservationSink|TestOpenAILivenessRecoveryObservability)$'`

Expected: PASS with matching tests executed for all three producer surfaces; source-backed selector substitutions are recorded in Deviations from Plan if reviewed children use different exact names.

Output:
```
ok  	iop/apps/node/internal/node	0.127s
ok  	iop/apps/edge/internal/service	0.057s
ok  	iop/apps/edge/internal/openai	0.126s
```

### Verification 4

Command: `rg --sort path -n 'iop_node_response_stalls_total|iop_edge_provider_health_evidence_total|iop_edge_liveness_recovery_eligibility_total|node_response_stall_observation|edge_provider_health_observation|edge_liveness_recovery_observation' agent-contract/inner/execution-runtime.md agent-contract/inner/edge-node-runtime-wire.md agent-spec/runtime/edge-node-execution.md`

Expected: output contains the exact reviewed metric/event names and no speculative name.

Output:
```
agent-contract/inner/execution-runtime.md:78:- `iop_node_response_stalls_total` (counter): labels `execution_path`, `provider_health`, `liveness_classification`, `attempt_fence`. Every claimed stall increments exactly one series.
agent-contract/inner/execution-runtime.md:80:- Dedicated structured log `node_response_stall_observation`: fields `execution_path`, `provider_health`, `liveness_classification`, `attempt_fence`, `idle_duration_ms`.
agent-contract/inner/execution-runtime.md:88:- `iop_edge_provider_health_evidence_total` (counter): labels `source`, `evidence_health`, `decision`. Records authoritative overlay decisions.
agent-contract/inner/execution-runtime.md:90:- Dedicated structured log `edge_provider_health_observation`: fields `source`, `evidence_health`, `decision`, `from_health`, `to_health`, `state_changed`.
agent-contract/inner/execution-runtime.md:98:- `iop_edge_liveness_recovery_eligibility_total` (counter): labels `execution_path`, `provider_health`, `commit_state`, `eligibility`. Records eligibility decisions per liveness cycle.
agent-contract/inner/execution-runtime.md:100:- Dedicated structured log `edge_liveness_recovery_observation`: fields `phase`, `execution_path`, `provider_health`, `commit_state`, `eligibility`, `recovery_result`.
agent-contract/inner/edge-node-runtime-wire.md:107:- Node emits `iop_node_response_stalls_total`, `iop_node_response_stall_duration_seconds`, and `node_response_stall_observation` locally after the stall terminal is assembled.
agent-contract/inner/edge-node-runtime-wire.md:108:- Edge emits `iop_edge_provider_health_evidence_total`, `iop_edge_provider_health_transitions_total`, and `edge_provider_health_observation` locally after the overlay decision is finalized.
agent-contract/inner/edge-node-runtime-wire.md:109:- Edge emits `iop_edge_liveness_recovery_eligibility_total`, `iop_edge_liveness_recovery_results_total`, and `edge_liveness_recovery_observation` locally per request lifecycle.
agent-spec/runtime/edge-node-execution.md:165:- Node owns local detection, cancellation, emission fencing, confirmed/unconfirmed ownership close, exact-target probe joining, connection-scoped observation sequencing, and the bounded `iop_node_response_stalls_total` / `iop_node_response_stall_duration_seconds` / `node_response_stall_observation` projections with closed label values.
agent-spec/runtime/edge-node-execution.md:166:- Edge owns reception-generation and immutable-lease validation, the generation-scoped runtime health overlay, `iop_edge_provider_health_evidence_total` / `iop_edge_provider_health_transitions_total` / `edge_provider_health_observation` projections with closed label values, effective admission/snapshot projection, and exact later CAPABILITIES recovery.
agent-spec/runtime/edge-node-execution.md:167:- The always-owned supported OpenAI ingress runtime owns commit, cancellation, side-effect, snapshot, shared-budget, candidate, and replay decisions, and exposes `iop_edge_liveness_recovery_eligibility_total` / `iop_edge_liveness_recovery_results_total` / `edge_liveness_recovery_observation` projections with closed label values.
agent-spec/runtime/edge-node-execution.md:180:- 2026-08-06: Mapped reviewed Node, Edge overlay, and OpenAI recovery observability producers to S06 behavior with deterministic test evidence. Node exposes `iop_node_response_stalls_total`, `iop_node_response_stall_duration_seconds`, and `node_response_stall_observation` (source: `apps/node/internal/node/liveness_observability.go`; test: `TestNodeLivenessObservability`). Edge service queue exposes `iop_edge_provider_health_evidence_total`, `iop_edge_provider_health_transitions_total`, and `edge_provider_health_observation` (source: `apps/edge/internal/service/provider_health_observability.go`; test: `TestProviderHealthObservability`, `TestProviderHealthObservabilityDoesNotExposeSentinels`). Edge OpenAI server exposes `iop_edge_liveness_recovery_eligibility_total`, `iop_edge_liveness_recovery_results_total`, and `edge_liveness_recovery_observation` (source: `apps/edge/internal/openai/liveness_recovery_observability.go`; test: `TestOpenAILivenessObservationSink`, `TestOpenAILivenessRecoveryObservability`). All projections carry only closed, low-cardinality label values and exclude raw payloads, credentials, and unbounded identifiers from metric labels and general logs. The wire protocol is unchanged.
```

### Verification 5

Command: `git diff -- agent-contract/inner/execution-runtime.md agent-contract/inner/edge-node-runtime-wire.md agent-spec/runtime/edge-node-execution.md agent-task/m-node-provider-execution-liveness-recovery/14+11,12,13_observability_contracts/CODE_REVIEW-cloud-G05.md`

Expected: only declared contract/spec and implementation-evidence edits appear.

Output:
```
diff --git a/agent-contract/inner/edge-node-runtime-wire.md b/agent-contract/inner/edge-node-runtime-wire.md
index 53c5ec0c..50e87d5c 100644
--- a/agent-contract/inner/edge-node-runtime-wire.md
+++ b/agent-contract/inner/edge-node-runtime-wire.md
@@ -17,6 +17,9 @@
   - `packages/go/credentiallease/envelope.go`
   - `apps/edge/internal/transport/connection_handlers.go`
   - `apps/edge/internal/service/model_queue_release.go`
+  - `apps/edge/internal/service/model_queue_snapshot.go`
+  - `apps/edge/internal/service/node_command.go`
+  - `apps/node/internal/node/command_handler.go`
   - `apps/edge/internal/service/status_provider.go`
   - `apps/edge/internal/node/mapper.go`
   - `apps/node/internal/adapters/config_set.go`
@@ -38,13 +41,15 @@ Edge는 Node 연결을 수락하고, Node는 연결 직후 등록 요청을 보

 ## 주요 흐름

-- register와 readiness: Node가 `RegisterRequest`를 보내고 Edge가 `RegisterResponse`로 수락 여부와 `NodeConfigPayload`를 돌려준다. accepted registration은 Node ID의 현재 ownership을 pending으로 claim할 뿐 dispatch 가능 상태가 아니다. Node는 config 적용, adapter start, session handler 설치 뒤 `NodeReadyRequest(node_id)`를 보내고, Edge가 current owner를 dispatch-ready로 전환한 뒤 `NodeReadyResponse`로 ack한다. 이 ready ack 전에는 run, provider tunnel, command, config-refresh push와 connected availability/event가 열리지 않는다.
+- register와 readiness: 수락된 하나의 TCP 연결(`TcpClient`)은 정확히 하나의 Node ID만 소유한다. 동일한 연결로 두 번째 Node ID 등록을 시도하면 첫 번째 binding과 generation을 바꾸지 않고 거부된다. Node가 `RegisterRequest`를 보내고 Edge가 `RegisterResponse`로 수락 여부와 `NodeConfigPayload`를 돌려준다. accepted registration은 Node ID의 현재 ownership을 pending으로 claim할 뿐 dispatch 가능 상태가 아니다. Node는 config 적용, adapter start, session handler 설치 뒤 `NodeReadyRequest(node_id)`를 보내고, Edge가 current owner를 dispatch-ready로 전환한 뒤 `NodeReadyResponse`로 ack한다. 이 ready ack 전에는 run, provider tunnel, command, config-refresh push와 connected availability/event가 열리지 않는다.
 - connectivity supervision: Node daemon은 Fx startup 전에 원격 연결 성공을 요구하지 않고 단일 supervisor goroutine이 initial dial과 established-session reconnect를 같은 policy로 직렬 처리한다. retryable 원격 실패는 재시도하고 local config/credential fatal error, 유한 retry exhaustion, local shutdown만 process terminal로 구분한다.
 - disconnect/reconnect: current dispatch-ready owner의 close/heartbeat timeout만 해당 connection generation을 fence한다. Edge는 같은 authoritative lifecycle에서 provider lease를 정확히 한 번 반환하고 resource를 offline/excluded로 만든 뒤 queue를 live candidate 기준으로 재평가한다. accepted Node의 ready transition은 새 generation resource를 활성화하고 기존 waiter를 즉시 pump한다. stale/rejected connection callback은 live state나 lifecycle event를 바꾸지 않는다.
 - execution: Edge가 `RunRequest`를 보내고 Node가 `RunEvent` stream으로 실행 상태를 보낸다.
 - provider raw tunnel: Edge가 기존 Edge-Node socket으로 `ProviderTunnelRequest`를 보내고 Node가 provider HTTP/SSE 요청을 연 뒤 `ProviderTunnelFrame` stream으로 provider status/header/body/end/error/usage 후보를 sequence와 함께 돌려준다. 이 경로는 OpenAI-compatible provider passthrough용이며 `RunEvent` 실행 stream과 분리된다.
 - response_stall_timeout_ms: `RunRequest.response_stall_timeout_ms`와 `ProviderTunnelRequest.response_stall_timeout_ms`는 int64 필드로, 선택된 provider의 response-stall timeout을 밀리초 단위로 운반한다. Zero는 Node가 문서화된 기본값(300000ms)을 적용함을 의미한다. Negative 또는 overflow 값은 Node 경계에서 router/provider 호출 전에 reject된다. Edge provider-pool dispatch는 winning candidate의 effective timeout을 각 요청에 복사한다. Direct/non-pool 호출은 wire에서 zero를 사용하고 Node 기본값을 적용한다.
-- response stall terminal: Node observes only the execution activity contract. On expiry it cancels and fences the local provider attempt, joins the bounded close-grace fence and an independent exact-target health probe without extending either serially, then emits exactly one normalized `RunEvent{type=error}` or tunnel `ProviderTunnelFrame{kind=ERROR}` with `failure_code=response_stalled`. Terminal metadata is allowlisted (three-way health evidence as the `provider_health` status paired with the `liveness_classification` normalization — `available`/`request_stalled`, `unavailable`/`provider_unhealthy`, or `unknown`/`health_unknown`; idle duration; Node-owned run/attempt identity; fence; adapter; target; and an optional connection-scoped `health_observation_seq`); it contains no caller-controlled identity, raw payload, credential, or `recovery_eligible`. `health_observation_seq` starts at one per connection and increases uniquely across the connection's normalized and tunnel observations; an unbound session omits it. Probe availability is evidence only and never resets progress, changes the fence, or authorizes retry. A confirmed fence is a capability hint only, not Node retry authorization.
+- response stall terminal: Node observes only the execution activity contract. On expiry it cancels and fences the local provider attempt, joins the bounded close-grace fence and an independent exact-target health probe without extending either serially, then emits exactly one normalized `RunEvent{type=error}` or tunnel `ProviderTunnelFrame{kind=ERROR}` with `failure_code=response_stalled` and populates the optional wire `ExecutionFailure` field (field 13 on `RunEvent`, field 15 on `ProviderTunnelFrame`). Terminal metadata is allowlisted (three-way health evidence as the `provider_health` status paired with the `liveness_classification` normalization — `available`/`request_stalled`, `unavailable`/`provider_unhealthy`, or `unknown`/`health_unknown`; idle duration; Node-owned run/attempt identity; fence; adapter; target; and an optional connection-scoped `health_observation_seq`); it contains no caller-controlled identity, raw payload, credential, or `recovery_eligible`. Nil and non-stalled failures leave wire `ExecutionFailure` absent while preserving legacy error string fields (`RunEvent.Error` / `ProviderTunnelFrame.Error`). `health_observation_seq` starts at one per connection and increases uniquely across the connection's normalized and tunnel observations; an unbound session omits it. Probe availability is evidence only and never resets progress, changes the fence, or authorizes retry. A confirmed fence is a capability hint only, not Node retry authorization.
+- Edge terminal handoff: transport reception identity, not payload identity, supplies `(node_id, connection_generation)`. Before a normalized or tunnel terminal can affect provider health, Edge compares that identity and the typed adapter/target evidence with the tracked immutable provider lease. A current terminal releases that lease exactly once even when optional health evidence is rejected. Edge adds `provider_id`, validated `provider_health`, and `recovery_handoff=confirmed` to every validated current bound stall before downstream routing, including sequence-stale request-local handoff; only a fresh `unavailable` observation lowers the separate runtime overlay. The handoff token is not replay approval, and Edge never adds `recovery_eligible` here.
+- CAPABILITIES recovery probe: Node resolves the requested adapter instance, runs the bounded fail-closed exact-target `ProbeHealth`, and returns stable `adapter_key`, `target`, normalized `provider_status`, and the next Session-owned `health_observation_seq`. Edge retains the command's dispatch node/generation and may clear one unavailable overlay only when a higher-sequence `available` response identifies exactly one same-generation provider binding. Empty, malformed, ambiguous, mismatched, stale, `unknown`, and `unavailable` results do not change the overlay.
 - precedence and ownership: request hard deadline, caller cancellation, and session disconnect retain their existing boundary when they win before the watchdog. A session lifetime context cancels active run and tunnel handlers on disconnect. If provider return is not confirmed during the bounded close grace, Node emits and fences the terminal but retains admission, run-manager, credential, and adapter ownership until the provider actually returns.
 - managed credential delivery: after provider selection, Edge attaches an exact `CredentialLeaseBinding` and a short-lived signed lease sealed to the selected Node. The Node opens it only after adapter-capacity admission and immediately before provider execution, verifies signature, recipient, scope, expiry, and replay state, injects the declared auth header in memory, then zeroes plaintext material.
 - provider-pool mixed dispatch: Edge service는 model group provider candidate를 선택한 뒤, 같은 selected provider/queue lease로 OpenAI-compatible provider에는 `ProviderTunnelRequest`, Ollama/native provider에는 normalized `RunRequest`를 보낸다. Edge-Node wire는 client-provided response path selector를 받지 않고, provider type만으로 후보를 제외하지 않는다.
@@ -70,6 +75,7 @@ Edge는 Node 연결을 수락하고, Node는 연결 직후 등록 요청을 보
 - `RunEvent.metadata["openai_tool_calls"]`: OpenAI-compatible provider adapter가 native `tool_calls`를 반환했을 때 완료 이벤트에 싣는 JSON 배열이다. Edge OpenAI-compatible 표면은 이 값을 `message.tool_calls` 또는 stream `delta.tool_calls`로 복원한다. provider assistant content 텍스트를 이 값으로 파싱/합성하지 않는다.
 - `RunEvent.metadata["openai_text_tool_fallback"]`: OpenAI-compatible provider adapter가 backend native tool API 거부 후 `tools`/`tool_choice`를 제거하고 text tool-call instruction으로 재시도했을 때 `"true"`를 싣는다. 이 instruction은 backend가 system role 위치를 거부하지 않도록 leading system message에 병합한다. Edge는 이 표시가 있는 실행에서만 assistant content의 text tool-call을 OpenAI-compatible `tool_calls`로 복원할 수 있다.
 - `NodeCommandRequest.type`: 실행이 아닌 조회/제어성 명령이다. adapter execution 요청과 섞지 않는다.
+- `NodeCommandResponse.result` for CAPABILITIES uses `adapter_key`, `target`, `provider_status`, and `health_observation_seq` as the stable recovery-evidence keys. `adapter` and `instance_key` remain diagnostic capability identity; arbitrary provider metadata is not accepted as recovery evidence.
 - `NodeConfigPayload.adapters`: Edge가 Node에 내려주는 adapter instance 설정이다.
 - `NodeReadyRequest.node_id`: `RegisterResponse`가 돌려준 Node identity다. Edge registry의 internal connection generation은 이 wire/config field로 노출하지 않으며, Edge는 `(node_id, current client)` ownership 비교로 stale ready를 거부한다.
 - `NodeReadyResponse.ready`: current pending owner의 첫 ready transition과 이미 ready인 같은 owner의 duplicate ready에서 true다. 첫 transition만 provider resource activation, stranded provider-pool waiter pump, `node.connected` event를 만든다. stale/superseded/rejected connection은 false와 reason을 받고 session을 닫아 reconnect해야 한다.
@@ -77,6 +83,7 @@ Edge는 Node 연결을 수락하고, Node는 연결 직후 등록 요청을 보
 - `NodeRuntimeConfig.concurrency`: legacy compatibility runtime metadata다. 실행 admission은 이 값을 node-wide global gate로 사용하지 않고 provider/resource capacity를 기준으로 한다. Node store 위치나 실행 작업 디렉터리는 이 runtime payload에 싣지 않는다.
 - `reconnect.interval_sec`, `reconnect.max_attempts`: initial connect와 established-session reconnect에 공통 적용된다. 명시적 `max_attempts=0`은 local shutdown까지 unlimited, 생략은 기본값 `10`, 양수는 정확한 유한 attempt limit, 음수는 validation error다. unlimited mode의 `interval_sec`는 양수여야 하며 생략은 기본값 `10`을 사용한다. 유한 exhaustion과 non-retryable 오류는 exit code 1, local shutdown은 정상 종료다.
 - `ProviderSnapshot`: legacy wire name을 유지하지만 Node 아래 resource/provider 상태 snapshot으로 해석한다. `category`가 `api`, `local_inference` resource kind를 나타내며, provider-pool dispatch 대상은 Edge config `models[].providers`가 참조한 resource뿐이다. `in_flight`와 `long_in_flight`는 `node_id + provider_id` lease state의 현재 점유다. `queued`는 Edge queue에서 해당 provider를 live candidate로 포함하는 고유 pending request 수이고 `long_queued`는 그중 long request 수이므로 여러 provider snapshot에 같은 request가 candidate pressure로 나타날 수 있다.
+- A current runtime-unavailable overlay preserves ProviderSnapshot catalog identity but projects `status=unavailable`, `health=unavailable`, and all effective capacity/load/counter fields as zero. The configured provider health is not rewritten. A newer connection generation does not inherit the old overlay.
 - configured Node가 disconnected/pending이면 Node snapshot은 `connected=false`를 유지하고 provider catalog entry도 남는다. enabled provider의 effective snapshot은 `status=unavailable`, `health=offline`, capacity/in-flight/queued/long-context 관련 수치가 모두 0이다. reconnect ready 뒤에는 같은 resource identity의 새 generation으로 configured capacity와 admission eligibility가 복구된다.
 - Node adapter instance는 normalized `RunRequest`와 `ProviderTunnelRequest`가 공유하는 local capacity gate를 사용한다. 이 gate는 Edge provider lease를 복제하는 분산 admission이 아니라 Edge queue를 우회한 실행으로부터 같은 backend를 보호하는 defense-in-depth다.

@@ -93,6 +100,16 @@ Edge는 Node 연결을 수락하고, Node는 연결 직후 등록 요청을 보
 - Do not send provider plaintext, at-rest ciphertext, the recipient private key, or the issuer private key in `NodeConfigPayload`, logs, metrics, events, or tunnel metadata.
 - Do not open a lease before adapter capacity admission, cache plaintext across requests, accept a lease for another Node/target/revision/generation, or fall back to a different same-model credential slot after a bound route fails.

+## 운영 증거 사영 경계
+
+Node stall, Edge provider-health overlay, and Edge OpenAI recovery operational projections are local observations derived from the established terminal, health-overlay, and recovery decisions. They introduce no new Node↔Edge frame, field, ordering rule, or retry semantic. The wire protocol remains unchanged by these projections.
+
+- Node emits `iop_node_response_stalls_total`, `iop_node_response_stall_duration_seconds`, and `node_response_stall_observation` locally after the stall terminal is assembled.
+- Edge emits `iop_edge_provider_health_evidence_total`, `iop_edge_provider_health_transitions_total`, and `edge_provider_health_observation` locally after the overlay decision is finalized.
+- Edge emits `iop_edge_liveness_recovery_eligibility_total`, `iop_edge_liveness_recovery_results_total`, and `edge_liveness_recovery_observation` locally per request lifecycle.
+
+Operational projections exclude raw payloads, credentials, caller-controlled identities, and unbounded identifiers from metric labels and general logs. Valid typed terminal metadata (e.g. `run_id`, `adapter`, `target` on the allowlisted stall metadata map) remains on the wire as already required by the typed terminal contract.
+
 ## 변경 시 확인할 코드/테스트

 - `proto/iop/runtime.proto`
diff --git a/agent-contract/inner/execution-runtime.md b/agent-contract/inner/execution-runtime.md
index 5df3ca7d..23ea4d1a 100644
--- a/agent-contract/inner/execution-runtime.md
+++ b/agent-contract/inner/execution-runtime.md
@@ -13,8 +13,13 @@
   - `packages/go/execution/failure.go`
   - `apps/node/internal/node/runtime_bridge.go`
   - `apps/node/internal/node/health_probe.go`
+  - `apps/node/internal/node/command_handler.go`
   - `apps/node/internal/node/liveness_watchdog.go`
   - `apps/node/internal/transport/session.go`
+  - `apps/edge/internal/service/model_queue_release.go`
+  - `apps/edge/internal/service/node_command.go`
+  - `apps/edge/internal/openai/stream_gate_runtime.go`
+  - `apps/edge/internal/openai/stream_gate_stall_recovery_test.go`

 ## Scope

@@ -36,10 +41,16 @@ The execution package defines host-neutral provider primitives. It owns provider
 - `NodeProviderConf.EffectiveResponseStallTimeoutMS()` returns the effective timeout for a provider candidate.
 - `RunRequest.ResponseStallTimeoutMS` and `ProviderTunnelRequest.ResponseStallTimeoutMS` carry the selected provider's effective timeout; zero on the wire means the Node applies the documented default.
 - The Node wire boundary normalizes zero to `300000` and rejects negative or overflow values before router/provider invocation.
-- `response_stalled` is a stable typed failure. Its allowlisted metadata includes the failure code, the joined three-way exact-target health evidence (Edge-visible `provider_health` status and normalized `liveness_classification`), idle duration, Node-owned run/attempt identity, the local close fence, adapter, target, and an optional connection-scoped `health_observation_seq`; caller metadata cannot override these values, and no raw payload, credential, or recovery signal is admitted.
+- `response_stalled` is a stable typed failure. Node transport mappers (`runEventToProto` and `tunnelFrameToProto`) populate the optional wire `ExecutionFailure` message only for `FailureCodeResponseStalled`, attaching a defensive clone of allowlisted metadata keys (`failure_code`, `provider_health`, `liveness_classification`, `idle_duration_ms`, `run_id`, `attempt_id`, `attempt_fence`, `adapter`, `target`, and `health_observation_seq`); nil and non-stalled failures leave wire `ExecutionFailure` absent while preserving legacy error string fields (`RunEvent.Error` / `ProviderTunnelFrame.Error`). Caller metadata cannot override these values, and no raw payload, credential, or `recovery_eligible` signal is admitted.
 - The Node watchdog starts from attempt admission, resets only on the documented progress dispositions, stops on provider terminal, and emits one typed stall terminal. It does not retry providers or infer recovery eligibility. `Retryable=true` means only that the local provider ownership fence was confirmed within the bounded close grace.
 - After the watchdog claims a stall it joins two independent bounded outcomes without extending either serially — the fixed close-grace fence and the exact-target health probe — then assembles exactly one allowlisted terminal. The joined `liveness_classification`/`provider_health` pair is exactly `request_stalled`/`available`, `provider_unhealthy`/`unavailable`, or `health_unknown`/`unknown` (fail-closed default). Provider availability observed here is evidence only: it never resets progress, changes the fence, revives output, or authorizes retry, and late provider output stays fenced.
 - `health_observation_seq` is a connection-scoped monotonic sequence sourced from the transport Session. A new connection starts at zero, so the first finalized observation is one; normalized and tunnel observations on the same connection share the source and receive unique, increasing values under concurrency. Internal or unbound execution paths omit the key entirely and never encode a process-global generation.
+- `ProviderPoolDispatchRequest` carries two request-local recovery-hint fields: `AvoidProviderID` (non-empty to prefer a runtime-eligible alternate over the avoided provider) and `AllowAvoidedProviderFallback` (explicit permission to retain the avoided provider when no alternate exists and it remains runtime eligible). The queue applies identical avoidance filtering to both initial and queued re-resolution. Zero values preserve current selection behavior. This is selection policy only: it does not create a retry loop, reserve a slot, change provider priority, persist the hints, or count retries. The fallback permission is always derived from exact probe-backed `available` evidence by the caller (never from current overlay state).
+- A Node `capabilities` command performs the same bounded exact-target `ProbeHealth` operation. Its stable result evidence is the requested adapter instance key (`adapter_key`), exact `target`, fail-closed normalized `provider_status`, and the next `health_observation_seq` from that same transport Session. Probe errors, unsupported probing, and adapter/instance/target mismatches report `unknown`; raw capability status is not recovery evidence.
+- Edge accepts a typed stall observation for provider-wide projection only after authoritative reception `(node_id, connection_generation)` matches the tracked immutable dispatch lease `(node_id, connection_generation, provider_id, adapter, target)`, the local attempt fence is confirmed, and the observation sequence is strictly newer. A current terminal still releases its lease exactly once when health evidence is absent, malformed, mismatched, or stale; a reception-owner mismatch changes neither overlay nor lease state.
+- Every validated current bound stall is annotated with Edge-owned `provider_id`, the validated `provider_health`, and `recovery_handoff=confirmed`, including an out-of-order terminal whose health projection is sequence-stale. Only a fresh `unavailable` observation lowers the generation-scoped runtime overlay. The token proves reception, lease binding, and local-fence handoff only; it is never `recovery_eligible` and never authorizes retry.
+- Every supported OpenAI Chat/Responses normalized or tunnel request enters one request-local StreamGate runtime, which is the sole liveness owner even when configured semantic filtering is disabled. That runtime may consume the confirmed handoff as a raw-free `response_stalled` provider error while its endpoint adapters preserve the disabled-semantic native status, headers, JSON/SSE/tunnel order, validation, usage, cancellation, and terminal behavior. It retains only the stable failure code, confirmed-handoff token, and `available|unavailable|unknown` health classification; Node/provider messages and arbitrary metadata are not copied. Exact replay additionally requires the existing uncommitted, uncancelled, side-effect-safe, snapshot-backed, shared-budget gate. A confirmed old terminal closes its Edge transport without another `CancelRun`; pool re-admission consumes the provider once as `AvoidProviderID`, with same-provider fallback only for exact `available` evidence.
+- The runtime overlay is keyed by `(node_id, connection_generation, provider_id)` and remains separate from configuration health. It excludes the provider from effective admission and projects it unavailable in status snapshots. Recovery requires a later CAPABILITIES result for the same current adapter/target mapping with strictly higher sequence and exact normalized `available`; malformed, ambiguous, stale-generation, unknown, and unavailable results are no-ops.

 ## Health probe contract

@@ -52,12 +63,54 @@ The execution package owns the stable, fail-closed probe outcome vocabulary cons
 - The Node probe coordinator (`ProbeHealth`) roots its own five-second bounded context from the background, re-checks that deadline/cancellation after the probe returns, validates exact adapter and target identity (including a pinned instance key when set), and feeds only the typed normalizer. It never copies arbitrary provider metadata.
 - `ResolveProbeFunc` returns `nil` for an adapter that does not implement `ProviderProber`; a `nil` hook makes `ProbeHealth` fail closed to `health_unknown` without invoking any endpoint.

-Probe completion is evidence only. The probe itself must never reset original request progress, change the attempt fence, authorize retry, sequence the watchdog terminal, drive the Edge overlay, or infer recovery. Node owns the stall-terminal join and the connection-scoped `health_observation_seq`; Edge reception-generation binding, stale-observation validation, the Edge health overlay, candidate exclusion, retry, recovery, and configuration remain owned by later slices.
+Probe completion is evidence only. The probe itself must never reset original request progress, change the attempt fence, authorize retry, sequence the watchdog terminal, directly mutate the Edge overlay, or infer recovery. Node owns the stall-terminal join and the connection-scoped `health_observation_seq`. Edge owns reception-generation and immutable-lease validation, the separate runtime overlay, candidate exclusion, snapshot projection, and exact later CAPABILITIES recovery. The ingress recovery host remains the sole owner of commit, cancellation, side-effect, budget, candidate, and replay eligibility decisions.

 ## Prohibited ownership

 The package must not own interactive shells, persistent processes, terminal emulation, working-directory mutation, resumable conversations, local quota probing, or arbitrary host command execution. It must not import application-internal packages or generated transport types.

+## Operational evidence projections
+
+The Node and Edge owners expose bounded operational projections derived exclusively from the established stall terminal, health-overlay, and recovery decisions documented above. These projections never widen the Node↔Edge wire protocol: they carry no new frame, field, ordering rule, or retry semantic, and they are emitted only after the authoritative decision is finalized.
+
+### Node stall observations (owner: Node process-global)
+
+- `iop_node_response_stalls_total` (counter): labels `execution_path`, `provider_health`, `liveness_classification`, `attempt_fence`. Every claimed stall increments exactly one series.
+- `iop_node_response_stall_duration_seconds` (histogram): same four labels. Samples the idle duration in seconds.
+- Dedicated structured log `node_response_stall_observation`: fields `execution_path`, `provider_health`, `liveness_classification`, `attempt_fence`, `idle_duration_ms`.
+- Label values are closed and low-cardinality: `execution_path` ∈ {`normalized`, `provider_tunnel`, `unknown`}; `provider_health` ∈ {`available`, `unavailable`, `unknown`}; `liveness_classification` ∈ {`request_stalled`, `provider_unhealthy`, `health_unknown`}; `attempt_fence` ∈ {`confirmed`, `unconfirmed`, `unknown`}.
+- Prohibited from metric labels and general logs: raw prompt/response, credential, caller metadata, `recovery_eligible`. High-cardinality inputs normalize to `unknown`.
+- Observer failure is fire-and-forget and never suppresses the terminal.
+- Source: `apps/node/internal/node/liveness_observability.go`; test: `apps/node/internal/node/liveness_observability_test.go::TestNodeLivenessObservability`.
+
+### Edge provider-health overlay observations (owner: Edge service queue process-global)
+
+- `iop_edge_provider_health_evidence_total` (counter): labels `source`, `evidence_health`, `decision`. Records authoritative overlay decisions.
+- `iop_edge_provider_health_transitions_total` (counter): labels `from_health`, `to_health`. Records overlay state transitions.
+- Dedicated structured log `edge_provider_health_observation`: fields `source`, `evidence_health`, `decision`, `from_health`, `to_health`, `state_changed`.
+- Label values are closed: `source` ∈ {`stall`, `probe`, `unknown`}; `evidence_health` ∈ {`available`, `unavailable`, `unknown`}; `decision` ∈ {`applied`, `rejected_stale`, `rejected_binding`, `rejected_ambiguous`, `inconclusive`}; `from_health`/`to_health` ∈ {`available`, `unavailable`, `unknown`}.
+- Prohibited from metric labels and general logs: provider, node, run, session, adapter, target, payload, or credential values.
+- Emitted post-decision after the queue lock releases; the queue does not wait for observer delivery.
+- Source: `apps/edge/internal/service/provider_health_observability.go`; test: `apps/edge/internal/service/provider_health_observability_test.go::TestProviderHealthObservability` and `TestProviderHealthObservabilityDoesNotExposeSentinels`.
+
+### Edge OpenAI recovery observations (owner: Edge OpenAI server request-local wrapper with process-global collectors)
+
+- `iop_edge_liveness_recovery_eligibility_total` (counter): labels `execution_path`, `provider_health`, `commit_state`, `eligibility`. Records eligibility decisions per liveness cycle.
+- `iop_edge_liveness_recovery_results_total` (counter): labels `execution_path`, `provider_health`, `recovery_result`. Records at most one final result per liveness cycle.
+- Dedicated structured log `edge_liveness_recovery_observation`: fields `phase`, `execution_path`, `provider_health`, `commit_state`, `eligibility`, `recovery_result`.
+- Label values are closed: `execution_path` ∈ {`normalized`, `provider_tunnel`, `unknown`}; `provider_health` ∈ {`available`, `unavailable`, `unknown`}; `commit_state` ∈ {`transport_uncommitted`, `stream_open`, `terminal_committed`, `unknown`}; `eligibility` ∈ {`eligible`, `no_owner`, `post_commit`, `unconfirmed_fence`, `caller_cancelled`, `tool_side_effect`, `budget_exhausted`, `no_candidate`, `same_provider_forbidden`, `other`}; `recovery_result` ∈ {`redispatched`, `plan_rejected`, `abort_failed`, `rebuild_failed`, `dispatch_failed`, `not_selected`, `terminal`, `other`}.
+- Prohibited from metric labels and general logs: correlation, attempt, run, session, model, provider, node, plan, shared_attempt_id, credential, or slot identifiers.
+- Each request owns one fresh wrapper; the collectors are process-global and registered once at package init.
+- Source: `apps/edge/internal/openai/liveness_recovery_observability.go`; test: `apps/edge/internal/openai/liveness_recovery_observability_test.go::TestOpenAILivenessObservationSink` and `TestOpenAILivenessRecoveryObservability`.
+
+### Fresh health recovery in provider snapshots
+
+A recovered provider appears in the existing Edge provider snapshot overlay as `status=available`, `health=available`, with effective capacity restored to configured values. The snapshot reflects the same `(node_id, connection_generation, provider_id)` key used by the runtime overlay. A newer connection generation does not inherit the old overlay.
+
+### Leakage boundary
+
+Operational projections exclude raw payloads, credentials, caller-controlled identities, and any unbounded identifier from metric labels and general structured logs. The exclusion applies to metric labels and general logs only; valid typed terminal metadata (e.g. `run_id`, `adapter`, `target` on the allowlisted stall metadata map) remains on the wire as already required by the typed terminal contract.
+
 ## Verification

 - `go test -count=1 ./packages/go/execution`
diff --git a/agent-spec/runtime/edge-node-execution.md b/agent-spec/runtime/edge-node-execution.md
index 043d9b99..51e1f3c2 100644
--- a/agent-spec/runtime/edge-node-execution.md
+++ b/agent-spec/runtime/edge-node-execution.md
@@ -26,7 +26,13 @@ source_evidence:
     notes: Node-side tunnel-tolerant heartbeat and reconnect transport
   - type: code
     path: apps/edge/internal/service/provider_tunnel.go
-    notes: Provider selection, credential binding validation, lease acquisition, and pre-send fencing
+    notes: Provider selection, credential binding validation, reception-aware terminal handoff, lease acquisition, and pre-send fencing
+  - type: code
+    path: apps/edge/internal/service/model_queue_release.go
+    notes: Immutable lease validation, generation/sequence-fenced runtime health overlay, recovery handoff annotation, and exactly-once release
+  - type: code
+    path: apps/edge/internal/service/node_command.go
+    notes: CAPABILITIES dispatch identity retention and exact available recovery evidence application
   - type: code
     path: apps/node/internal/node/tunnel_handler.go
     notes: Provider tunnel handling and recipient-sealed credential lease consumption
@@ -44,7 +50,13 @@ source_evidence:
     notes: Signed scope validation, recipient sealing, expiry, replay, and exact binding verification
   - type: test
     path: apps/node/internal/node/command_test.go
-    notes: Closed provider commands, correlation, and cancellation regressions
+    notes: Closed provider commands plus fail-closed exact CAPABILITIES health and Session sequence regressions
+  - type: test
+    path: apps/edge/internal/service/provider_health_overlay_test.go
+    notes: S04 binding, stale evidence, normalized/tunnel release races, overlay projection, and CAPABILITIES recovery evidence
+  - type: test
+    path: apps/edge/internal/openai/stream_gate_stall_recovery_test.go
+    notes: S05 always-owned OpenAI recovery, new attempt/provider selection, shared budget, old-transport close, and guard terminals
   - type: test
     path: apps/edge/internal/transport/heartbeat_test.go
     notes: Edge heartbeat liveness profile regression
@@ -78,9 +90,13 @@ The shared `packages/go/execution` package contains provider lifecycle, registry
 | normalized execution | `adapter + target`으로 provider 실행을 선택하고 ordered `RunEvent` stream을 반환한다. |
 | provider raw tunnel | 선택된 provider의 HTTP/SSE를 `ProviderTunnelRequest`/`ProviderTunnelFrame`으로 relay하며 순서와 단일 terminal outcome을 보장한다. |
 | response-stall activity contract | 선택된 provider의 response-stall timeout을 normalized/tunnel request에 보존한다. Node는 wire zero를 `300000ms`로 해석하고 invalid raw value를 adapter 호출 전에 거부한다. Runtime event의 terminal type은 payload/usage보다 우선하며 non-terminal usage는 progress다. |
-| Node stall watchdog | Node가 normalized run과 raw tunnel에 하나의 activity watchdog을 적용한다. progress만 timer를 reset하며, stall은 `response_stalled` terminal 하나와 Node-owned safe metadata를 만든다. stall claim 뒤에는 bounded close grace fence와 독립 exact-target health probe를 직렬 확장 없이 join한다. close grace 안에 provider return이 확인된 경우만 `Retryable` capability hint를 준다. |
+| Node stall watchdog | Node가 normalized run과 raw tunnel에 하나의 activity watchdog을 적용한다. progress만 timer를 reset하며, stall은 `response_stalled` terminal 하나와 Node-owned safe metadata를 만들어 normalized `RunEvent`와 raw `ProviderTunnelFrame` wire의 optional typed `ExecutionFailure` 필드에 싣는다. stall claim 뒤에는 bounded close grace fence와 독립 exact-target health probe를 직렬 확장 없이 join한다. close grace 안에 provider return이 확인된 경우만 `Retryable` capability hint를 준다. |
 | Node health evidence join | stall terminal에 three-way health evidence를 싣는다: `provider_health` status와 `liveness_classification` normalization이 `available`/`request_stalled`, `unavailable`/`provider_unhealthy`, `unknown`/`health_unknown` 쌍으로 fail-closed된다. probe 성공은 progress reset·fence 변경·retry authority가 아니며 late output은 fenced 상태를 유지한다. |
 | health observation sequence | transport Session이 connection-scoped monotonic `health_observation_seq`를 소유한다. 새 connection은 0에서 시작해 첫 finalized observation이 1이며, 같은 connection의 normalized/tunnel observation이 source를 공유해 동시에도 유일 증가값을 받는다. internal/unbound 경로는 key를 생략한다. |
+| Edge terminal health handoff | Edge validates authoritative reception node/generation plus the immutable provider/adapter/target lease before applying typed stall evidence. Every validated current bound stall receives `provider_id`, validated health, and `recovery_handoff=confirmed`, while only fresh unavailable evidence lowers a separate runtime overlay; the token never grants replay eligibility. Every valid current terminal still releases its lease exactly once. |
+| CAPABILITIES recovery | Node runs the same bounded exact-target `ProbeHealth` and returns stable adapter/target/status plus the next Session sequence. Edge recovers exactly one matching current-generation unavailable provider only from a strictly newer `available` result; malformed, ambiguous, stale, unknown, and unavailable responses are no-ops. |
+| recovery candidate preference | `ProviderPoolDispatchRequest` carries `AvoidProviderID` and `AllowAvoidedProviderFallback`. Every admission (initial and queued re-resolution) prefers a runtime-eligible alternate over the avoided provider; only the explicit fallback flag (derived from exact probe-backed `available` evidence) permits re-selecting the avoided provider when no alternate exists. Zero values preserve current selection. This is selection policy only: no retry loop, slot reservation, priority change, persistence, or retry counter. |
+| OpenAI typed-stall consumption | Every supported Chat/Responses normalized or tunnel request has one unconditional runtime liveness owner, independent of configured semantic activation. It converts only the Edge-confirmed typed stall handoff into a raw-free StreamGate event, owns pre-commit eligibility, and closes the already fenced old transport before re-admission; Node does not grant replay authority. |
 | tunnel-tolerant liveness | Edge와 Node는 30초 heartbeat interval과 45초 response wait를 공통으로 사용해 긴 prompt prefill이나 streaming backpressure 중의 정상 connection을 조기에 끊지 않는다. |
 | reconnect/generation fencing | 현재 connection이 종료되면 해당 generation만 fence하고 Node supervisor가 reconnect한다. Heartbeat wait를 넘긴 경우의 close reason은 `heartbeat_timeout`이다. |
 | cancellation/command | `run_id`로 현재 run만 취소하며 command는 capabilities, transport status, Ollama API tunnel로 제한한다. |
@@ -95,6 +111,8 @@ The shared `packages/go/execution` package contains provider lifecycle, registry

 IOP no longer provides persistent shell sessions, terminal emulation, process resume, local working-directory execution context, arbitrary host commands, or local quota/status probing.

+The current spec maps reviewed Node and Edge observability producers to S06 behavior and deterministic tests. Node exposes bounded stall counters/histograms and dedicated structured logs with closed label values and raw-payload exclusion. Edge service queue exposes bounded overlay evidence/transition counters and dedicated structured logs with closed label values and identity exclusion. Edge OpenAI server exposes bounded eligibility/results counters and dedicated structured logs with closed label values and identifier exclusion. All projections are local observations and do not widen the wire protocol.
+
 ## 주요 흐름

 ```mermaid
@@ -144,11 +162,19 @@ Heartbeat interval/wait는 protobuf field가 아닌 양쪽 transport 구현의 l

 - 30/45초 liveness profile은 provider 응답 token 상한이나 model context window를 늘리지 않는다. 요청 중단 원인 판정 시 model 설정과 transport disconnect를 별도로 확인한다.
 - 45초를 넘겨 실제 heartbeat response가 없는 connection은 기존과 같이 오프라인 처리하고 reconnect한다.
-- Node watchdog은 local detection, cancellation, emission fence, confirmed/unconfirmed ownership close, 그리고 stall terminal에 대한 exact-target health probe join과 connection-scoped observation sequencing을 소유한다. Edge reception-generation binding, stale-observation validation, Edge health overlay, Node retry, `recovery_eligible`, recovery, candidate selection은 이 slice 밖의 후속 작업으로 남는다. Hard deadline and connection disconnect continue to take precedence over a simultaneous stall timer.
+- Node owns local detection, cancellation, emission fencing, confirmed/unconfirmed ownership close, exact-target probe joining, connection-scoped observation sequencing, and the bounded `iop_node_response_stalls_total` / `iop_node_response_stall_duration_seconds` / `node_response_stall_observation` projections with closed label values.
+- Edge owns reception-generation and immutable-lease validation, the generation-scoped runtime health overlay, `iop_edge_provider_health_evidence_total` / `iop_edge_provider_health_transitions_total` / `edge_provider_health_observation` projections with closed label values, effective admission/snapshot projection, and exact later CAPABILITIES recovery.
+- The always-owned supported OpenAI ingress runtime owns commit, cancellation, side-effect, snapshot, shared-budget, candidate, and replay decisions, and exposes `iop_edge_liveness_recovery_eligibility_total` / `iop_edge_liveness_recovery_results_total` / `edge_liveness_recovery_observation` projections with closed label values.
+- Node retry and `recovery_eligible` remain prohibited. Hard deadline and connection disconnect continue to take precedence over a simultaneous stall timer.
+- Operational projections never widen the wire protocol; they carry no new frame, field, ordering rule, or retry semantic.

 ## 변경 기록

 - 2026-08-02: provider tunnel의 긴 prompt prefill과 streaming backpressure를 정상 traffic으로 허용하도록 Edge/Node heartbeat profile을 30초 interval/45초 wait로 복원한 현재 구현과 회귀 검증을 반영했다 (`apps/edge/internal/transport/server.go`, `apps/node/internal/transport/client.go`).
 - 2026-08-04: provider response-stall timeout의 config validation, selected-candidate propagation, Node adapter-visible retention, and activity classification contract를 반영했다.
-- 2026-08-04: Added the shared Node run/tunnel watchdog coordinator, serialized tunnel emission fence, pre-provider admission cleanup, disconnect-bound handler lifetime, and deterministic S01/S02 manual-clock evidence. Provider health probing and Edge-owned recovery remain future slices.
-- 2026-08-04: Joined the bounded close-grace fence and the independent exact-target health probe into one stall terminal carrying three-way health evidence, and added the connection-scoped `health_observation_seq` sourced from the transport Session. Edge reception-generation binding, stale validation, Edge health overlay, recovery, and candidate selection remain future slices.
+- 2026-08-04: Added the shared Node run/tunnel watchdog coordinator, serialized tunnel emission fence, pre-provider admission cleanup, disconnect-bound handler lifetime, and deterministic S01/S02 manual-clock evidence.
+- 2026-08-04: Joined the bounded close-grace fence and the independent exact-target health probe into one stall terminal carrying three-way health evidence, and added the connection-scoped `health_observation_seq` sourced from the transport Session.
+- 2026-08-05: Added authoritative Edge terminal handoff, immutable lease binding, generation/sequence-fenced runtime provider health, exactly-once normalized/tunnel release, and fail-closed Session-sequenced CAPABILITIES recovery without config-health mutation or replay authorization.
+- 2026-08-05: Added runtime-local OpenAI consumption of confirmed typed stalls, including cancel-free old-transport close and provider-pool avoidance hints for ExactReplay.
+- 2026-08-05: Made supported OpenAI Chat/Responses normalized and tunnel liveness ownership unconditional and added S05 recovery/guard evidence independent of semantic policy activation.
+- 2026-08-06: Mapped reviewed Node, Edge overlay, and OpenAI recovery observability producers to S06 behavior with deterministic test evidence. Node exposes `iop_node_response_stalls_total`, `iop_node_response_stall_duration_seconds`, and `node_response_stall_observation` (source: `apps/node/internal/node/liveness_observability.go`; test: `TestNodeLivenessObservability`). Edge service queue exposes `iop_edge_provider_health_evidence_total`, `iop_edge_provider_health_transitions_total`, and `edge_provider_health_observation` (source: `apps/edge/internal/service/provider_health_observability.go`; test: `TestProviderHealthObservability`, `TestProviderHealthObservabilityDoesNotExposeSentinels`). Edge OpenAI server exposes `iop_edge_liveness_recovery_eligibility_total`, `iop_edge_liveness_recovery_results_total`, and `edge_liveness_recovery_observation` (source: `apps/edge/internal/openai/liveness_recovery_observability.go`; test: `TestOpenAILivenessObservationSink`, `TestOpenAILivenessRecoveryObservability`). All projections carry only closed, low-cardinality label values and exclude raw payloads, credentials, and unbounded identifiers from metric labels and general logs. The wire protocol is unchanged.
```

### Verification 6

Command: `git diff --check`

Expected: no whitespace errors.

Output:
```
PASS
```

---

> **[IMPLEMENTING AGENT — BEFORE SAVING] Have you filled in every implementation-owned section?**
> If anything is blank, go back and fill it in before saving this file.
> Leave review-agent-only sections unchanged.

## Section Ownership

| Section | Owner | Note |
|---------|-------|------|
| Header comment, Overview, Review Agent Instructions | Fixed at stub creation | Implementing agent must not modify or execute these (archive, complete.log, and task-directory archive move are review-agent only) |
| Archive Evidence Snapshot | Fixed at stub creation from plan when present | Implementing agent uses it as default prior-loop context; read only the specific archive files cited there when more detail is required |
| Implementation Item Completion (item names) | Fixed at stub creation | Implementing agent checks `[ ]` → `[x]` only |
| Implementation Checklist (item text/order) | Fixed at stub creation from plan | Implementing agent checks `[ ]` → `[x]` only |
| Review-Only Checklist | Review agent only | Implementing agent must not modify or check this section |
| Deviations from Plan, Key Design Decisions | Implementing agent | Replace placeholder text with actual content |
| Reviewer Checkpoints | Fixed at stub creation | Pre-filled from plan |
| Verification Results (section headings + commands) | Fixed at stub creation | Implementing agent fills in command output only; command changes require a `Deviations from Plan` entry |
| Code Review Result | Review agent appends | Not included in stub |

## Code Review Result

- Overall Verdict: FAIL
- Dimension Assessment:
  - Correctness: Fail — the documented observation timing does not match the synchronous production call order.
  - Completeness: Fail — the bounded OpenAI safe-log vocabulary and the living spec's S06 verification/source-evidence matrix are incomplete.
  - Test Coverage: Pass — fresh package and focused observability tests pass and exercise the three producer surfaces.
  - API Contract: Fail — two timing statements and the safe-log schema are not faithful to the implemented contract.
  - Code Quality: Pass — no production-code defect, debug residue, dead code, or unrelated implementation change was found in this documentation-only packet.
  - Implementation Deviation: Fail — REFACTOR-1's exact timing/vocabulary requirement and REFACTOR-2's deterministic source/test evidence requirement are not fully satisfied.
  - Verification Trust: Pass — all six planned commands were rerun successfully and their current results agree with the recorded evidence.
  - Spec Conformance: Fail — SDD S06 requires bounded operational evidence and deterministic evidence mapping, but the current contract/spec text leaves the gaps below.
- Findings:
  - Required R1 — `agent-contract/inner/execution-runtime.md:93` says the queue does not wait for observer delivery, but `apps/edge/internal/service/provider_health_observability.go:168` calls the observer synchronously and `apps/edge/internal/service/provider_health_observability_test.go:218` proves the terminal handler waits until the blocking observer returns. `agent-contract/inner/edge-node-runtime-wire.md:107` also says Node emits after the stall terminal is assembled, while `apps/node/internal/node/liveness_watchdog.go:227` and `apps/node/internal/node/liveness_watchdog.go:324` invoke the observer before constructing the normalized/tunnel terminal. Replace both statements with the exact implemented ordering: finalized stall/overlay evidence, queue unlock before Edge observation, synchronous observer delivery, and Node observation before terminal construction/delivery; do not imply asynchronous delivery.
  - Required R2 — `agent-contract/inner/execution-runtime.md:100` names the OpenAI safe-log fields but omits their full bounded value contract. The implementation emits `phase` as `idle|eligible_pending`, permits empty `eligibility`/`recovery_result` on lifecycle rows, and currently normalizes `provider_health` to `unknown` because the immutable observation carries no health (`apps/edge/internal/openai/liveness_recovery_observability.go:335` and `apps/edge/internal/openai/liveness_recovery_observability.go:370`). Document those current log semantics separately from the metric-label vocabulary so the contract does not imply evidence the producer cannot emit.
  - Required R3 — `agent-spec/runtime/edge-node-execution.md:5` does not include the three S06 observability source/test pairs in structured `source_evidence`, and `agent-spec/runtime/edge-node-execution.md:153` omits the focused OpenAI observability verification entirely. Add the exact Node, Edge overlay, and OpenAI observability source/test entries and deterministic S06 commands, including the provider-health sentinel guard, so the living spec's stated S06 mapping is directly reproducible rather than existing only in the change-history prose.
- Routing Signals: `review_rework_count=1`, `evidence_integrity_failure=false`
- Next Step: Invoke the plan skill in `prepare-follow-up` mode with Required R1, R2, and R3 as direct fixes, then archive this pair and materialize the freshly routed follow-up pair.
