<!-- task=m-agent-readable-repository-refactor/13_inventory_query plan=6 tag=REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_IQRY -->

# Inventory query 검증 evidence 신뢰성 복구 계획

## 이 파일을 읽는 구현 에이전트에게

아래 고정 검증 명령을 그대로 실행한 뒤 `CODE_REVIEW-local-G03.md`의 구현 에이전트 소유 섹션에 실제 stdout/stderr와 종료 상태를 채우고 active 파일을 그대로 둔 채 리뷰 준비 상태를 보고한다. 종결, 로그 아카이브, `complete.log` 작성은 code-review 전용이다. 선택된 Milestone의 `구현 잠금 > 결정 필요` 항목이 실제 구현을 막는 경우에만 review stub의 `사용자 리뷰 요청`에 연결 근거를 기록하고 멈춘다. 구현 중 사용자에게 직접 질문하거나 선택지를 제시하거나 `request_user_input`을 호출하거나 `USER_REVIEW.md`/로그/`complete.log`를 만들지 않는다. 환경·secret·서비스 차단, 일반 범위 변경, 후속 에이전트가 채울 수 있는 evidence 공백은 사용자 리뷰 요청이 아니다.

## 배경

provider map assertion과 focused/package/full 회귀는 리뷰어의 fresh 실행에서 통과했다. 다만 이전 계획의 `go test ... -list | grep -qx ...`는 `set -o pipefail`에서 producer가 SIGPIPE `141`을 반환하고 `grep -q`는 stdout을 출력하지 않으므로, 기록된 exit 0과 테스트명 출력은 신뢰할 수 없다. production/test 코드는 바꾸지 않고 pipefail-safe 명령과 실제 출력만 다시 확보한다.

## 사용자 리뷰 요청 흐름

선택된 Milestone의 `구현 잠금 > 결정 필요`만 `agent-ops/skills/common/_templates/implementation-user-review-request-section.md` 형식으로 active review stub에 기록한다. 구현 중 직접 사용자 prompt는 금지하며, 요청 검증과 실제 `USER_REVIEW.md` 작성은 code-review가 담당한다.

## Roadmap Targets

- Milestone: `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md`
- Milestone link: [Milestone 문서](agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md)
- Task ids:
  - `inventory-query`: env/model/node/provider selector로 canonical inventory의 bounded 결과를 얻는 결정적 query 경로
- Completion mode: check-on-pass

## Archive Evidence Snapshot

- Prior task: `agent-task/m-agent-readable-repository-refactor/13_inventory_query`
- Archived plan: `agent-task/m-agent-readable-repository-refactor/13_inventory_query/plan_local_G04_5.log`
- Archived review: `agent-task/m-agent-readable-repository-refactor/13_inventory_query/code_review_local_G04_5.log`
- Verdict: FAIL
- Required: 1 — pipefail에서 실패하는 list/grep pipeline과 재현 불가능한 stdout 때문에 최종 검증 evidence를 신뢰할 수 없음
- Suggested: 0
- Nit: 0
- Affected files: `CODE_REVIEW-local-G03.md`; production/test source 변경 없음
- Verification evidence: 리뷰어 fresh 실행에서 원래 pipeline은 `pipeline_statuses=141,0`, 파일 기반 two-step list check는 PASS했다. focused/package/full Go test, compiled dev/dev-corp selector, binary 0/1/2/help, readability ratchet, gofmt와 `git diff --check`도 PASS했다.
- Roadmap carryover: `inventory-query`는 신뢰 가능한 active review evidence로 PASS하기 전까지 미완료다.
- Allowed narrow reread: 위 archived plan/review 두 파일만 추가 세부가 필요할 때 읽는다.

## 분석 결과

### 읽은 파일

- `agent-ops/rules/project/rules.md`
- `agent-ops/rules/common/rules-roadmap.md`
- `agent-ops/rules/common/rules-agent-spec.md`
- `agent-ops/rules/project/domain/testing/rules.md`
- `agent-ops/rules/project/domain/platform-common/rules.md`
- `agent-ops/skills/common/router.md`
- `agent-ops/skills/common/code-review/SKILL.md`
- `agent-ops/skills/common/plan/SKILL.md`
- `agent-ops/skills/common/_templates/implementation-user-review-request-section.md`
- `agent-test/local/rules.md`
- `agent-test/local/testing-smoke.md`
- `agent-test/local/platform-common-smoke.md`
- `agent-roadmap/current.md`
- `agent-roadmap/phase/automation-runtime-bridge/PHASE.md`
- `agent-roadmap/phase/automation-runtime-bridge/milestones/agent-readable-repository-refactor.md`
- `agent-spec/index.md`
- `agent-spec/runtime/provider-pool-config-refresh.md`
- `agent-contract/index.md`
- `agent-contract/inner/edge-config-runtime-refresh.md`
- `scripts/inventory-query/main.go`
- `scripts/inventory-query/provider_query.go`
- `scripts/inventory-query/main_test.go`
- `scripts/inventory-query/provider_query_test.go`
- `agent-task/m-agent-readable-repository-refactor/13_inventory_query/plan_local_G04_5.log`
- `agent-task/m-agent-readable-repository-refactor/13_inventory_query/code_review_local_G04_5.log`

### SDD 기준

Milestone은 `SDD: 불필요`다. 외부 API/proto/config schema나 runtime 책임 경계를 바꾸지 않는 동작 보존형 저장소 리팩터링이며, 이번 후속 작업은 코드 변경 없이 검증 evidence만 복구한다.

### 테스트 환경 규칙

`test_env=local`이다. `agent-test/local/rules.md`, `agent-test/local/testing-smoke.md`, `agent-test/local/platform-common-smoke.md`를 읽었다. 현재 checkout에서 fresh focused/package/full Go test, compiled canonical selector와 0/1/2/help, worktree readability ratchet, gofmt와 `git diff --check`를 적용한다. 외부 provider/runtime, Docker, endpoint, secret은 필요하지 않고 binary/cache/JSON/list evidence는 `/tmp`에만 둔다. Go test cache 결과는 허용하지 않고 `-count=1`을 사용한다.

### 테스트 커버리지 공백

- provider map exact path/value/order/dedupe assertion은 현재 `TestQueryProviderMatchesMapEntries`가 충족한다.
- 코드/시나리오 공백은 없다. 남은 공백은 pipefail-safe list 확인과 실제 stdout/stderr evidence뿐이다.

### 심볼 참조

rename/remove 없음. source symbol이나 call site를 변경하지 않는다.

### 분할 판단

split decision policy를 재평가했다. 하나의 검증 명령과 active review evidence만 보완하는 동일 책임이며 API, call-site, 도메인, 테스트 전략 경계가 없다. 분할하면 동일 명령과 evidence를 중복하므로 기존 `13_inventory_query` 단일 follow-up이 안전하다.

### 범위 결정 근거

`scripts/inventory-query/**`, canonical inventory, deploy skill, agent-spec, agent-contract, roadmap, readability baseline/threshold/allowlist는 수정하지 않는다. 변경 범위는 active review evidence에 한정한다. Spec update not needed: 구현 동작과 근거 경로가 바뀌지 않는다.

### 빌드 등급

`local-G03`. 하나의 재현 가능한 shell pipeline을 파일 기반 two-step 명령으로 교체하고 실제 출력만 확보하는 bounded verification 작업이다.

## 구현 체크리스트

- [ ] pipefail-safe 파일 기반 test list 확인과 fresh focused/package/full Go test, canonical compiled binary 계약, worktree readability audit, diff 검증을 고정 명령으로 실행해 실제 stdout/stderr와 종료 상태를 확보한다.
- [ ] CODE_REVIEW-*-G??.md의 구현 에이전트 소유 섹션을 실제 구현 내용과 검증 출력으로 채운다. 이 항목이 완료되기 전에는 구현이 완료된 것이 아니다.

### [REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_IQRY-1] Pipefail-safe 검증 evidence 복구

#### 문제

`code_review_local_G04_5.log:154`는 최종 검증 전체가 exit 0이었다고 기록하지만, `plan_local_G04_5.log:176`의 `go test ... -list | grep -qx ...`는 `set -o pipefail`에서 `pipeline_statuses=141,0`으로 실패한다. `grep -q`는 stdout을 출력하지 않으므로 archived review의 테스트명 출력도 실제 명령 출력일 수 없다.

#### 해결 방법

list 출력을 `/tmp` 파일에 완전히 쓴 뒤 별도 `grep`으로 exact test name을 확인하고, 파일 내용과 각 명령의 실제 출력을 active review에 기록한다.

Before (`plan_local_G04_5.log:176`):

```bash
go test ./scripts/inventory-query -list '^TestQueryProviderMatchesMapEntries$' | grep -qx 'TestQueryProviderMatchesMapEntries'
```

After:

```bash
go test ./scripts/inventory-query -list '^TestQueryProviderMatchesMapEntries$' > /tmp/iop-inventory-query-test-list.out
cat /tmp/iop-inventory-query-test-list.out
grep -qx 'TestQueryProviderMatchesMapEntries' /tmp/iop-inventory-query-test-list.out
```

#### 수정 파일 및 체크리스트

- [ ] `CODE_REVIEW-local-G03.md` — corrected 명령, 실제 stdout/stderr, 종료 상태와 source 미변경 사실을 기록한다.

#### 테스트 작성

새 테스트는 작성하지 않는다. 기존 `TestQueryProviderMatchesMapEntries`가 source behavior를 충분히 검증하며 이번 Required는 테스트 로직이 아니라 실행 evidence 신뢰성 문제다.

#### 중간 검증

```bash
export GOCACHE=/tmp/iop-inventory-query-evidence-gocache
mkdir -p "$GOCACHE"
set -euo pipefail
go test ./scripts/inventory-query -list '^TestQueryProviderMatchesMapEntries$' > /tmp/iop-inventory-query-test-list.out
cat /tmp/iop-inventory-query-test-list.out
grep -qx 'TestQueryProviderMatchesMapEntries' /tmp/iop-inventory-query-test-list.out
go test -count=1 ./scripts/inventory-query -run '^TestQueryProviderMatchesMapEntries$'
```

모든 명령이 exit 0이어야 하고 list 파일에는 exact test name 행이 한 번 있어야 한다.

## 수정 파일 요약

| 파일 | 항목 |
|------|------|
| `CODE_REVIEW-local-G03.md` | REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_REVIEW_IQRY-1 |

## 최종 검증

```bash
export GOCACHE=/tmp/iop-inventory-query-evidence-gocache
mkdir -p "$GOCACHE"
set -euo pipefail
gofmt -d scripts/inventory-query/main.go scripts/inventory-query/provider_query.go scripts/inventory-query/main_test.go scripts/inventory-query/provider_query_test.go
go test ./scripts/inventory-query -list '^TestQueryProviderMatchesMapEntries$' > /tmp/iop-inventory-query-test-list.out
cat /tmp/iop-inventory-query-test-list.out
grep -qx 'TestQueryProviderMatchesMapEntries' /tmp/iop-inventory-query-test-list.out
go test -count=1 ./scripts/inventory-query -run '^TestQueryProviderMatchesMapEntries$'
go test -count=1 ./scripts/inventory-query
go build -o /tmp/iop-inventory-query-evidence ./scripts/inventory-query
/tmp/iop-inventory-query-evidence --env dev --provider gx10-vllm > /tmp/iop-inventory-evidence-dev-provider.json
/tmp/iop-inventory-query-evidence --env dev-corp --provider corp-dgx-spark-01-ornith > /tmp/iop-inventory-evidence-corp-provider.json
python3 - <<'PY'
import json

with open("/tmp/iop-inventory-evidence-dev-provider.json", encoding="utf-8") as handle:
    dev = json.load(handle)
with open("/tmp/iop-inventory-evidence-corp-provider.json", encoding="utf-8") as handle:
    corp = json.load(handle)

dev_paths = {item["path"]: item["value"] for item in dev["matches"]}
corp_paths = {item["path"]: item["value"] for item in corp["matches"]}
assert isinstance(dev_paths["model.active_edge_model_group.providers.gx10-vllm"], dict)
assert isinstance(dev_paths["nodes[1].provider"], dict)
assert corp_paths["model.aliases.ornith:35b.providers[0]"] == "corp-dgx-spark-01-ornith"
assert isinstance(corp_paths["nodes[0].provider"], dict)
PY
set +e
/tmp/iop-inventory-query-evidence --help >/tmp/iop-inventory-evidence-help.out 2>/tmp/iop-inventory-evidence-help.err
help_rc=$?
/tmp/iop-inventory-query-evidence --env dev --node definitely-not-a-node >/tmp/iop-inventory-evidence-zero.out 2>/tmp/iop-inventory-evidence-zero.err
zero_rc=$?
/tmp/iop-inventory-query-evidence --env unsupported >/tmp/iop-inventory-evidence-error.out 2>/tmp/iop-inventory-evidence-error.err
error_rc=$?
set -e
test "$help_rc" -eq 0
test "$zero_rc" -eq 1
test "$error_rc" -eq 2
test -s /tmp/iop-inventory-evidence-help.out
test ! -s /tmp/iop-inventory-evidence-help.err
test ! -s /tmp/iop-inventory-evidence-zero.out
test ! -s /tmp/iop-inventory-evidence-error.out
python3 scripts/readability_audit.py --check --input-mode worktree --output /tmp/iop-inventory-readability-evidence-final.json
go test -count=1 ./... | tee /tmp/iop-inventory-evidence-go-test-all.out
git diff --check
```

모든 명령은 exit 0, gofmt/diff-check와 `grep -q`는 무출력이어야 한다. List stdout은 `cat` 명령의 실제 출력으로만 기록하고, readability audit은 baseline/threshold/allowlist 변경 없이 새 위반 0건이어야 한다.

모든 코드 변경 완료 후 반드시 `CODE_REVIEW-*-G??.md`의 구현 에이전트 소유 섹션을 채운다. 이 파일 작성이 구현의 마지막 단계다.
