# Session 2026-05-21 — Review + Live-verification Checklist

> Browser-side verification plan for the 19 PRs merged on
> 2026-05-21 (commits `3ba609f` … `49201fd`). Use this file as
> a worksheet — check items off as the operator confirms each
> path. **Block the Option-A Phase 3 entry until every 🔴 row
> is verified.**

---

## 0. Scope

This checklist covers ONLY this session's 19 merged PRs:

| # | PR | Topic |
|---|---|---|
| 1 | #364 | gitignore — SQLite WAL/SHM |
| 2 | #365 | fix — ruff F401 |
| 3 | #366 | docs — graph evolution memo |
| 4 | #367 | PR-11a-1 event entity helpers |
| 5 | #368 | PR-11a-2 event admin POST + lift |
| 6 | #370 | PR-11c event time-bucket filter |
| 7 | #371 | PR-11b ingest emit |
| 8 | #373 | UI sync (event color) |
| 9 | #374 | UI-IA Phase 2 stale tests |
| 10 | #376 | PR-11 tail — PUT event occurred_at |
| 11 | #377 | cognitive backend |
| 12 | #378 | cognitive UI |
| 13 | #379 | doc sync (cognitive) |
| 14 | #380 | LLM mapping UI |
| 15 | #381 | doc sync (LLM mapping) |
| 16 | #382 | history stale-row correction |
| 17 | #383 | feedback-stats UI |
| 18 | #384 | doc sync (feedback) |
| 19 | #385 | admin.js split inventory |

Of these:
- **3 are docs-only sync** (#379/#381/#384) — no live verification needed
- **3 are docs-only design/inventory** (#366/#382/#385) — no live verification needed
- **2 are infra/CI fixes** (#364/#365) — `git status` clean = verified
- **11 touch live behaviour** — checklist below

---

## 1. Pre-flight (1 minute)

Before any test:

- [ ] `.env` 의 `JAMES_LLM_MODEL` 확인 — `gemma3:12b` (권장) 또는 default `gemma4:e4b`
  - 4B 모델 사용 시 PR-11b ingest emit 일부 stage 실패 가능 (메모 `ali_demo_model_checkpoint.md`)
- [ ] 서버 재시작 — 본 세션의 `.env`-leak prevention chore (#364) 가 적용된 상태
- [ ] `git pull origin main` 가 `49201fd` 또는 그 이후 head
- [ ] 로그인 → admin role 확인 (PR-O5 default-deny 유지: 비로그인 → external)

---

## 2. PR-11 graph evolution — event entity end-to-end (🔴 critical)

배경: 5번째 entity_type "event" 가 라이브에 처음 들어가는 path. PR-11a-1 ~ PR-11c + PR-11b + #376 묶음.

### 2.1 admin POST /admin/graph/event 단독

- [ ] 환경 변수 `JAMES_GRAPH_EDIT=1` set 확인
- [ ] admin → graph 페이지 (또는 `curl` 또는 brower devtools) 에서:
  ```
  POST /admin/graph/event
  body: {"api_key":"...", "name":"테스트 이벤트", "occurred_at":"2026-01-10"}
  ```
- [ ] 응답: `{ok: true, entity_id: "e_event_xxxxxxxx", path: "wiki/entity/prod/event/<normalized>_<8hex>.md"}`
- [ ] 디스크 확인: `wiki/entity/prod/event/테스트_이벤트_xxxxxxxx.md` 생성됨, frontmatter 에 `entity_type: event`, `occurred_at: 2026-01-10`, `occurred_at_precision: day`, `sources: [{role: manual, doc_id: null, weight: 1.0, ts: ...}]`
- [ ] graph 페이지 새로고침 → 새 노드 추가 보임
- [ ] 노드 색상이 **rose/coral (#fb7185)** — 다른 4 type (cyan/amber/lavender/slate) 와 명백히 구분됨
- [ ] graph 페이지 좌측 범례에 5번째 row "event" / "사건" 표시 (lang toggle 양쪽 확인)

### 2.2 PR-11b ingest emit (LLM 추출)

⚠️ **default 모델이 gemma4:e4b 인 경우 4B 한계로 fail 가능 — gemma3:12b 권장**

- [ ] 어떤 file 에 명확한 시간 축 entity 가 포함된 짧은 doc 1개 업로드. 예시 content:
  ```
  2026년 1월 10일, SEC가 비트코인 spot ETF 11개를 일괄 승인.
  ```
- [ ] 추출 결과 admin Memory tab 에서 확인:
  - "2026 비트코인 ETF 승인" 같은 event entity 가 생성됐는가? (type=event, occurred_at=2026-01-10 가까운 값)
  - 또는 fallback 으로 concept 으로 들어왔다면 stdout 로그에 `[INGEST] event entity '...' missing/invalid occurred_at — falling back to concept` 확인
- [ ] 모델별 동작 메모:
  - gemma3:12b: event 인식 + 정상 emit (예상)
  - gemma4:e4b: concept 으로 떨어질 가능성 높음 (의도된 fallback)
- [ ] **회귀 체크**: 같은 doc 의 entity 갯수 / 다른 type 비율이 이전과 비슷 (4 type 의 prompt 변화로 인한 회귀 없음)

### 2.3 PR-11c 시간 윈도우 필터

- [ ] 1-2개 event 노드 더 만들어 두기 (다른 occurred_at):
  ```
  POST /admin/graph/event  body: {..., "name":"Q1 결과", "occurred_at":"2026-04-15"}
  POST /admin/graph/event  body: {..., "name":"Q2 결과", "occurred_at":"2026-07-15"}
  ```
- [ ] `GET /admin/graph/events?api_key=...&occurred_after=2026-03-01&occurred_before=2026-06-01` 호출
- [ ] 응답에 Q1 만 포함, Q2 와 첫 "테스트 이벤트" (1/10) 제외 확인
- [ ] 두 bound 모두 없으면 모든 event 반환:
  - `GET /admin/graph/events?api_key=...`
- [ ] 잘못된 bound (예: `occurred_after=yesterday`) → 400 응답

### 2.4 PR-11 tail (#376) — PUT event occurred_at

- [ ] 첫 "테스트 이벤트" (entity_id 기록해 두기) 의 occurred_at 을 PUT 으로 갱신:
  ```
  PUT /admin/graph/node
  body: {"api_key":"...", "entity_id":"e_event_xxxxxxxx", "patch":{"occurred_at":"2026-01-11"}}
  ```
- [ ] 응답: `changed_fields: ["occurred_at"]`
- [ ] frontmatter 에 새 값 반영, 기존 occurred_at_precision (day) 유지
- [ ] entity_id 변경 안 됨 (불변 invariant)
- [ ] 파일명 stale 인 점 확인 (`<normalized>_<8hex>.md` 의 hash 가 원래 date 기반) — 이건 의도. memo §5.2 / commit message 에 명시
- [ ] non-event 노드 (예: 어떤 person/concept) 에 같은 PUT 보내면 `occurred_at` 무시되고 noop 응답 (200 + empty changed_fields)

### 2.5 회귀 — 4 기존 entity type

- [ ] 기존 person/org/concept/document 노드들 graph 에 정상 표시 (색상 변함 없음)
- [ ] 기존 노드 클릭 시 detail panel 정상 (PR-O1 #277 회귀 없음)
- [ ] STEP 7 bench 1회: `python scripts/bench.py --suite=step7 --check` → `OK — within step7 baseline tolerances`

---

## 3. Cognitive toggle UI (#378) — admin Configure (🟠 watch)

배경: 6 cognitive feature flag 를 admin UI 에서 토글.

- [ ] admin → ⚙️ 설정 → "🧠 Cognitive Features" section 위치 확인 (Server Settings 와 Web Search 사이)
- [ ] 6 row 다 렌더: verify / rerank (default ON, 토글 ON) + fact_check / planner / query_rewrite / reflect (default OFF, 토글 OFF)
- [ ] 각 row 의 sub-line 에 `JAMES_DISABLE_VERIFY` 등 env 이름 + `default ON/OFF` + module 경로 표시
- [ ] reflect 토글 클릭 → 우측 라벨 "OFF" → "ON" 즉시 전환 (cosmetic)
- [ ] "Save Cognitive Flags" 클릭 → 토스트 "✅ Cognitive flags saved (1)"
- [ ] 새 tab/창에서 chat 시도 → reasoning panel 에 reflect step 출현 확인 (이게 backend 동작 증명)
- [ ] **lang toggle (en/ko)**:
  - "🧠 Cognitive Features" ↔ "🧠 인지 기능"
  - "Save Cognitive Flags" ↔ "인지 기능 저장"
  - hint 가 양쪽 locale 정상 표시 (dynamic render i18n 적용 검증)
- [ ] **session-only 인지**: 토글 ON 한 채로 서버 재시작 → 다시 admin Memory 들어가서 토글 상태 확인 → boot `.env` value 로 복귀 (의도). hint 가 이를 안내함을 사용자가 확인했는지

---

## 4. LLM Task → Model UI (#380) — admin Configure (🟠 watch)

배경: 5 canonical task 별 LLM 모델 매핑.

- [ ] admin → ⚙️ 설정 → "🤖 LLM Task → Model" section 위치 확인 (Server Settings 와 Cognitive Features 사이)
- [ ] 5 row 렌더: general / classify / extract / coding / vision
- [ ] 각 dropdown 에 ollama 설치된 모델 + "(default — config.GEMMA_MODEL)" 옵션
- [ ] 기존에 `workspace/llm_selection.json` 에 매핑이 있었다면 해당 row pre-selected
- [ ] coding row 를 `qwen2.5-coder:32b` 로 변경 → "Save LLM Selections" → 토스트 "✅ LLM selections saved (1)"
- [ ] 페이지 새로고침 → 변경 사항 영구 (workspace/llm_selection.json 에 기록됨)
- [ ] coding row 를 "(default)" 로 변경 → 저장 → `workspace/llm_selection.json` 에서 해당 키 삭제
- [ ] Ollama 다운 시뮬레이션 (필요 시): `/admin/llm/installed` 가 빈 list → section 이 "No models installed" 메시지 정상 표시
- [ ] **lang toggle**:
  - "🤖 LLM Task → Model" ↔ "🤖 작업별 LLM 매핑"
  - 5 task label 양쪽 locale 정상

---

## 5. Feedback stats card (#383) — admin Memory (🟠 watch)

배경: `/feedback/stats/` 의 5-stat strip.

- [ ] admin → 🧠 Memory tab → "📊 사용자 피드백 집계" section 위치 확인 (Memory cards 와 long-term 사이)
- [ ] 5 stat 보임: Total / Positive / Negative / Positive ratio / Tracked directions
- [ ] 깨끗한 환경에서 모두 0 + ratio "(no signal yet)"
- [ ] chat 에서 답변 받고 👍 또는 👎 버튼 클릭 → Memory tab 새로고침 → 숫자 갱신
- [ ] ratio 계산이 zero-total 가드: total=0 일 때 "(no signal yet)", total>0 일 때 percentage
- [ ] backend 가 error 시뮬레이션 (DevTools network → block `/feedback/stats/`) → section 이 빨강 에러 메시지 표시, 주변 Memory tab 의 long-term + sessions table 은 정상 (defensive try/catch 검증)
- [ ] **lang toggle**: 5 label 양쪽 locale (Total signals ↔ 총 신호, Positive ↔ 긍정, etc.)

---

## 6. History stale-row correction (#382) — 회귀 확인 (🟢 verify)

배경: `POST /history/sessions/rename/` 와 `GET /history/long-term/` 이 이미 wired 라고 doc 정정. 코드 변경 0.

- [ ] chat sidebar → "대화 이력" 모드 → 세션 list → 한 row 의 ✏️ 이름 클릭 → prompt → 새 이름 입력 → 저장 → list 새로고침 시 새 이름 반영 (rename endpoint 동작 확인)
- [ ] admin → 🧠 Memory tab → "장기 기억 (세션 요약)" table 가 비어있지 않으면 데이터 표시 (long-term endpoint 동작 확인)

---

## 7. UI sync / docs (🟢 verify)

PR #373 (graph color), #379/#381/#384 (mapping doc sync), #385 (inventory) 는 코드 변경 0 또는 minimal — 라이브 영향 정의:

- [ ] graph 페이지 새로 고침 시 노드 색상 정상 (변경 없는 4 entity type) — #373 의 회귀 확인용
- [ ] mapping doc 카운트 (137 endpoints, 99/137 IA core 99) 가 직관적 — 사용자가 직접 doc 읽기 (선택)

---

## 8. UI-IA Phase 2 stale tests (#374) — CI 만 (🟢 verified)

이건 main 의 깨진 7 테스트 fix. CI 그린 = verified. 추가 라이브 검증 없음.

---

## 9. 자메스 invariant 회귀 — 전체

본 세션 19 PR 가 자메스의 7 invariant 어디 하나라도 깬다면 라이브 검증에서 드러남:

- [ ] **PolicyEngine + ABAC gates**: 비로그인 → /admin/* 403 정상
- [ ] **`entity_id` 불변성**: PR #376 PUT event 후 entity_id 변경 안 됨 확인 (위 §2.4)
- [ ] **Knowledge Cascade `sources[]` 4-role**: 새 event 노드의 sources 에 role=manual (admin POST) / role=extract (LLM ingest) 정합
- [ ] **external default-deny**: 비로그인 사용자가 chat 시도 → internal_rag 거부, web-only 답변 (PR-O5 #314 보존)
- [ ] **CR-E 인간 승인 게이트**: self-evolution 관련 어떤 PR 도 본 세션에 없음 — 자동 검증
- [ ] **5-agent cap**: cognitive Phase 4 미진입 — 자동 검증
- [ ] **Session writes never escape upward**: PR-11d MemoryLoom date hook 미진입 — 자동 검증

---

## 10. Option-A Phase 3 진입 gate

Option A (admin.html → 3 HTML 페이지 분할) 진입 **전** 필수:

- [ ] §2 (graph evolution) 의 12개 항목 모두 ✅
- [ ] §3 (cognitive toggle) 의 토글 동작 + lang toggle 모두 ✅
- [ ] §4 (LLM mapping) 의 selection 저장 + retrieve 모두 ✅
- [ ] §5 (feedback stats) 의 렌더 + lang toggle 모두 ✅
- [ ] §6 (history stale) 의 rename + long-term 모두 ✅
- [ ] §9 (invariant) 의 PolicyEngine / entity_id / sources / external default-deny 모두 ✅
- [ ] STEP 7 bench `--check` → OK

---

## 11. 발견된 회귀 / 새 이슈 (기록란)

라이브 검증 중 발견된 항목을 여기에 기록 → 후속 fix PR 의 입력.

### 11.1 PR-11b 완성도 결함 — RESOLVED 2026-05-21

| 발견일 | PR (의도) | 증상 | severity | 후속 |
|---|---|---|---|---|
| 2026-05-21 | #371 (PR-11b) | LLM (gemma3:12b) 가 정확히 `type=event` + `occurred_at` emit 했지만 wiki/entity/<src>/event/ 에 entity 0건 생성. ingest path 의 3 layer 가 차례로 drop / silent fallback / id mismatch. | **high** — 사용자 가시 기능이 dead code | **fix PR** — 3 layer 모두 패치 + integration regression test 추가 |

세부 근본원인 — `core/wiki_generator.py` 의 3 layer 가 PR-11b 머지 시점에
함께 갱신되지 않음:

1. **`_ALLOWED_EXTRACT_TYPES`** (line 28) — frozenset 에 `"event"` 누락
   → `_is_safe_extracted_entity` 가 line 930 에서 silent drop
2. **`process_document_for_entities` 의 payload build** (line 730)
   — `ent["occurred_at"]` / `ent["occurred_at_precision"]` 안 carry
   → `create_entity_file` 의 event branch 가 항상
     `validate_occurred_at("")` 실패 → fallback to concept
3. **`created_ids.append(eid)` 의 hash** (line 753)
   — `_generate_entity_id(name, etype)` (4-type 용 hash) 사용
   → PR-11a-2 의 `_generate_event_entity_id(name, occurred_at,
     precision)` 와 다른 id 가 list 에 들어감
   → file 의 actual entity_id 와 list 의 entity_id 가 mismatch
   → 향후 cross-doc aggregation / id 조회 깨짐

### 11.2 관계없는 발견 (별 트랙 / 메모)

PR-11b 검증 중 부수적으로 관찰된 항목 — 본 fix PR scope 아님:

| 항목 | 내용 | 트랙 |
|---|---|---|
| **gemma4:e4b 의 event 미인식** | 4B 모델 (자메스 default) 이 PR-11b prompt 의 4번째 type `event` 를 raw JSON 응답에 emit 안 함. raw extract dump 확인 결과 gemma4:e4b 의 응답에 `type=event` 항목 0건. **이건 모델 한계** — prompt 가 아무리 명확해도 4B 가 새 type 의 conservative bias 못 넘음. 메모 `ali_demo_model_checkpoint.md` + 핸드오버 `v0.3.x-gemma4-feedback-track.md` 의 5-stage 실패 패턴과 정합. **권고**: event ingest 가 의도된 만큼 작동하려면 `.env` 의 `JAMES_LLM_MODEL=gemma3:12b` (또는 그 이상) 영구 설정. 4B 사용 시 event entity 는 admin POST path 로만 (ingest 미작동). | gemma4-feedback-track |
| **Trust system 의 cross-source 동작** | `source_type="test"` 로 ingest 시도해도 production wiki 의 기존 entity 와 trust conflict 발생 (memory_trust 의 consistency score 가 source_type 무관). production wiki 와 같은 이름의 entity 가 있는 doc 을 test 모드에서 ingest → trust score 0 → write reject. **본 PR-11b 와 무관한 관찰**. **잠재 영향**: source_type 격리의 정신 (production 무영향 검증) 이 trust layer 에서 깨짐. | 별 사이클 — `core/memory/memory_trust.py` 의 source_type 인지 도입 검토 |

---

## 12. 검토 메타

- 작성: 2026-05-21 session, 최초 19 PR closure 후 (이후 §11.1
  fix PR + §11.2 별 발견 추가로 23 PR 까지 확장)
- 작성자: 2026-05-21 session (Claude Opus 4.7)
- 다음 사이클 시작 전제: §10 모든 row ✅ + §11 의 critical severity 모두 해소

---

## 13. 2026-05-22 진입 가이드 (내일 세션 첫 액션)

### 13.1 현재 검증 진행 상태 (세션 종료 시점 2026-05-21)

| Section | 상태 |
|---|---|
| §1 Pre-flight | 미진행 — 다음 세션 첫 액션 |
| §2 PR-11 series | §2.2 (ingest emit) **✅ 검증 완료** — §11.1 의 PR #387 가 결함 해소 path. §2.1 / 2.3 / 2.4 / 2.5 미진행. |
| §3 Cognitive toggle (#378) | **미진행** — 다음 세션이 lang-toggle path 진행 예정. **본 항목 의 검증 path 5 phase 는 본 세션 마지막에 chat 으로 정리됨 — 다음 세션이 chat 기록 또는 본 §13.2 참조** |
| §4 LLM mapping (#380) | 미진행 |
| §5 Feedback stats (#383) | 미진행 |
| §6 History stale (#382) | 미진행 |
| §7 UI sync / docs | 미진행 (회귀-only, 낮은 우선순위) |
| §9 invariant matrix | 미진행 |
| §10 Phase 3 gate | 미진행 |

### 13.2 §3 cognitive 토글 검증 — 5 phase 가이드 (2026-05-21 chat 에서 도출)

코드 read 로 미리 추정: `applyTranslations()` 가 DOM 전체 sweep +
`setLang()` 가 매번 호출 → **자동 retranslate path 정상 작동
예상**. 그러나 Phase 3 / Phase 5 에서 회귀 가능성.

#### Phase 1 — 첫 로드 (현재 lang 으로 표시 OK?)

- admin → ⚙️ 설정 페이지
- 🧠 Cognitive Features section 의 6 row label / hint / save 버튼
  이 현재 lang 으로 정확히 표시되는지

#### Phase 2 — lang toggle 즉시 전환 (가장 중요)

- 우측 상단 lang toggle (KO ↔ EN)
- cognitive section 의 모든 label 가 0.5초 안에 다른 lang 으로
  즉시 바뀌는가?

#### Phase 3 — navigation round-trip 후 일관성

- settings → 다른 탭 (Memory 등) → settings 다시 진입
- cognitive section 의 label 가 현재 lang 정확히 표시?

#### Phase 4 — hardcoded ON/OFF span 의 의도성 확인

- toggle 클릭 시 우측 ON/OFF span 즉시 전환
- lang=ko 시에도 "ON"/"OFF" 영문 그대로 — **의도된 hardcode**
  (검증 결과가 의도와 다른지만 확인)

#### Phase 5 — 같은 패턴의 다른 2 section

- LLM mapping section (#380) 도 lang toggle 동작
- Memory tab 의 feedback stats card (#383) 도 동일

#### 회귀 발견 시 DevTools 진단

```javascript
// Console 에서
localStorage.getItem('james_lang')       // 현재 lang
typeof applyTranslations                  // 함수 정의 확인
applyTranslations()                       // 수동 호출 → 정상화 시
                                          //   → setLang 의 timing 문제
```

소요 추정: **8분** (회귀 없을 시) / **+5분** (회귀 진단 시).

### 13.3 §3 외 다른 라이브 검증 path

§2.1 (admin POST /admin/graph/event) 가 가장 작은 단위 검증.
`JAMES_GRAPH_EDIT=1` 설정 후 curl 또는 admin UI 의 graph editor
에서 event 생성 → graph 페이지의 rose/coral 노드 확인.

### 13.4 라이브 검증 발견 시 후속 path

- ✅ 모두 정상 → 다음 라이브 검증 항목 진행
- ⚠️ 회귀 발견 → §11.1 형식으로 기록 + 즉시 fix PR (본 세션의
  PR #387 처럼 — 같은 정공법 패턴)
- ❌ 큰 회귀 → Phase 3 진입 보류, fix 우선

---

## 한국어 한 줄 결론

본 세션 23 PR 의 정적 검증은 **2353 tests pass + ruff clean**.
라이브 검증은 사용자 영역 — 본 체크리스트 §1~§9 를 순서대로
진행하면 약 30-45분 소요. §11.1 (PR-11b 결함) 은 이미 PR #387 로
해소 — 다음 세션은 §3 cognitive 토글 검증부터 시작 (§13.2 가이드).
모든 row ✅ 후 Option-A Phase 3 (admin.html 3-페이지 분할) 진입 안전.
