Skip to main content

verification-query-moves-the-metric

배선이 도달했는지 재려고 잡은 지표를, 확인하는 쿼리 자체가 움직이는 경우 — `pg_stat_user_tables.seq_scan` 을 지표로 쓰면 `count(*)` 확인이 카운터를 올려 거짓 양성이 된다. 기준선을 문서로 넘겨받으면 다음 세션이 자기 확인 쿼리를 성공으로 오독한다. 트리거 - "카운터가 늘었으면 배선된 것", 스캔/히트 카운터를 증거로 삼기, 기준선을 인수인계에 적기, 관측 지표 설계.

Jump to install

Source facts

Repository
blas1n/claude-skills
Last source activity
August 20, 2026 at 09:23
Detected SKILL.md language
Korean
Stars
2
Forks
0

Install options

The review-first prompt is selected by default. You can switch to a direct command or download a local copy.

Review the source files

Read SKILL.md and any companion files shown by SkillsMP before deciding whether to install.

Showing SKILL.md

SKILL.md
Source instructions · Read-only preview
name
verification-query-moves-the-metric
description
배선이 도달했는지 재려고 잡은 지표를, 확인하는 쿼리 자체가 움직이는 경우 — `pg_stat_user_tables.seq_scan` 을 지표로 쓰면 `count(*)` 확인이 카운터를 올려 거짓 양성이 된다. 기준선을 문서로 넘겨받으면 다음 세션이 자기 확인 쿼리를 성공으로 오독한다. 트리거 - "카운터가 늘었으면 배선된 것", 스캔/히트 카운터를 증거로 삼기, 기준선을 인수인계에 적기, 관측 지표 설계.
version
1.0.0
task_types
["debugging","evaluation","design"]
triggers
[{"pattern":"'이 값이 늘었으면 코드가 실제로 돌았다'는 형태의 실증 계획"},{"pattern":"pg_stat / 캐시 히트 / 액세스 카운터를 배선 증거로 사용"},{"pattern":"인수인계 문서에 지표 기준선을 적어 다음 세션에 넘길 때"}]
category
trap
# 확인하는 행위가 지표를 움직인다 ## Problem "이 코드가 실제로 프로덕션에서 돌기 시작했나"를 재려고 **읽기 카운터**를 지표로 잡는다. 그런데 **확인 쿼리가 그 카운터를 올린다.** BSVibe 실측 (2026-08-20). 전임 세션이 인수인계에 이렇게 적었다: > 검증법: `note_embeddings` 의 스캔 카운터 델타. > **기준선: `seq_scan=196, idx_scan=40`.** 다음 settle 이후 다시 재서 늘었으면 > 컴파일러가 실제로 볼트를 읽은 것이다. 다음 세션이 확인해보니 **197** 이었다. "늘었다 → 배선 성공"으로 읽힐 자리였다. 대조 실험: ``` 읽기만(select seq_scan …): 198 select count(*) from note_embeddings ← 이게 곧 seq scan 읽기만 다시: 199 ``` `count(*)` 한 번이 카운터를 **1** 올린다. 196→199 의 증가분은 **전부 확인 쿼리 자신**이었고 실제 settle 은 **0회**였다. `idx_scan` 은 40 그대로. - 증상: 지표가 "조금씩" 오른다. 프로듀서 로그·행 생성 같은 다른 증거는 하나도 없다. - 근본 원인: 관측 대상과 관측 도구가 **같은 통계 카운터를 공유**한다. - 흔한 오해: "읽기 카운터는 프로덕션 코드가 읽을 때만 오른다" — psql 도 클라이언트다. ## Solution ### 1. 관측이 건드리지 않는 축을 골라라 | 나쁨 | 좋음 | |---|---| | `seq_scan` (모든 `count(*)` 가 올린다) | 프로듀서가 남기는 **구조화 로그** (`ingest_compile_batch_complete`) | | 캐시 히트 카운터 | 그 경로가 만드는 **행의 존재** (`activity_type='settle'`) | | "테이블이 읽혔나" | "그 읽기가 만들어낸 **산출물**이 있나" | **원칙: 읽기가 아니라 쓰기를 세라.** 쓰기는 확인 쿼리가 만들 수 없다. ### 2. 그래도 카운터를 쓴다면 확인 SQL 에 `count(*)` 를 넣지 마라 ```sql -- 나쁨: 한 문장 안에서 지표를 오염시킨다 select (select count(*) from t)||' rows, seq='||seq_scan from pg_stat_user_tables …; -- 좋음 select seq_scan, idx_scan from pg_stat_user_tables where relname='t'; ``` ### 3. 기준선을 인수인계에 적을 때는 **오염 조건을 함께** 적어라 기준선 숫자만 넘기면 다음 세션은 그 숫자를 신뢰한다. 지표가 어떻게 오염되는지를 같이 적지 않으면 **문서가 거짓 양성을 만들어낸다.** ```markdown -- 오염 없이 읽기 (count(*) 를 절대 같이 치지 마라) select seq_scan, idx_scan from pg_stat_user_tables where relname='note_embeddings'; -- 기준선: idx_scan = 40 ← 이쪽을 봐라. seq_scan 은 측정으로 오른다. ``` ### 4. 델타가 작으면 먼저 자기 자신을 의심하라 배선이 도달했다면 보통 **한 자릿수가 아니다**. `+1`, `+3` 처럼 확인 횟수와 비슷한 델타는 관측자 효과부터 배제해라 — 대조 실험이 30초면 끝난다: ```bash 읽기만 → 값 기록 → 확인 쿼리 한 번 → 읽기만 → 값 비교 ``` ## Verification - [ ] 확인 쿼리를 N번 반복했을 때 지표가 N만큼 오르지 **않는다** - [ ] 지표 상승이 프로듀서 측 증거(로그·행)와 **함께** 나타난다 - [ ] 인수인계에 적은 기준선에 "이렇게 재라 / 이건 오염된다"가 붙어 있다 ## Related - `absence-measurement-validity-check` — 반대 방향: 0을 쟀는데 프로듀서가 꺼져 있던 경우 - `activity-recording-drift-invalidates-historical-counts` — 과거 카운트가 기록 방식 변경으로 무효 - `acceptance-gate-must-measure-delta-not-state` — 게이트는 상태가 아니라 델타를 재야 한다
View on GitHub