understatus 0.7.0

A calm, unobtrusive macOS statusline addon for AI coding CLIs (Claude Code): CPU/memory/disk/network + session info with a quiet glyph theme.
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
# HANDOFF — understatus (+ lterm statusline 통합)

> 다음 세션/에이전트용 핸드오프. 제품은 원래 **statusticon** 코드네임이었다가 출시 시 **understatus**로 개명. 온디스크 디렉터리는 여전히 `statusticon/`이지만 제품/크레이트/레포/바이너리는 전부 **understatus**.
>
> **최신 세션 = §0·NOW (2026-06-13): walk-up 블로커 해소 — lterm 조사로 verdict 확정 = cwd-only(walk-up No-go). ← 여기부터 읽기.** 그 전(06-12, git pill 아이콘 SF Symbol 수정 PR #21 + 잔여 backlog Goal 3건 PR #22/#23/#24)은 §0·NOW-1, 06-11(v0.5.0/v0.6.0 릴리스 + 설치 하위호환 + ctx 튜닝 + node24)은 §0·PREV, 06-10(lterm 경로 git branch pill 구현·머지)은 §0(릴리스 상세 블록쿼트 포함), 06-09(cmux 네이티브 status pills 실렌더)는 §0A, 06-08(ctx 소멸 fix + 라우팅 인프라)은 §0B, 06-07은 §0C, Phase 1 배경은 §A, v0.3.0 릴리스 배경은 §C.

---

## ⚠️ 먼저 읽기 — 로컬 툴체인 깨짐 (양쪽 레포 공통)

**Homebrew `rustc`/`cargo`가 깨져 있다.** `/opt/homebrew/bin/rustc`가 없는 `libLLVM.dylib`를 참조 → bare `cargo`/`rustc`/`clippy`/`rust-analyzer` 실패(dyld 에러, 가끔 오해의 exit 0). `/opt/homebrew/bin`이 `~/.cargo/bin`보다 PATH 앞이라 **bare `cargo`는 깨진 쪽으로 resolve됨.**

**항상 rustup 툴체인 사용** (understatus·lterm **둘 다**):
```bash
export PATH="$HOME/.cargo/bin:$PATH"   # ~/.cargo/bin/cargo = stable-aarch64, 정상
```
- **rust-analyzer/IDE 진단은 가짜다**(phantom E0308, 실제 사용 중인 항목에 dead_code 등). **IDE 진단 무시, rustup `cargo`/`clippy` 출력만 신뢰.** (이번 세션에도 IDE가 `parse_lterm_input` 등을 dead로 표시했으나 rustup clippy는 클린.)
- `gtimeout` 없음 → 타임아웃은 background+polling kill 패턴으로.
- x86_64 크로스빌드는 로컬 실패 → CI(macos-14). 네이티브 arm64 빌드/테스트는 rustup으로 정상.

---

## §0·NOW. 최신 세션 (2026-06-13) — walk-up 블로커 해소 + P1 FP-free walk-up 구현 (PR #25)  ← **여기부터 읽기**

> **Goal**: 06-12 세션이 남긴 유일한 블로킹 backlog(walk-up branch 도출)의 선결 블로커 — "lterm은 `git_worktree`를 무엇으로 도출하며 셸 `cd`를 추적하는가?" — 를 lterm 레포 조사로 해소하고, 그에 따른 올바른 트랙(P1 walk-up)을 **구현**한다.
>
> **현재 상태: 블로커 해소 + P1 FP-free walk-up 구현 + quad-review-loop 2라운드 수렴 + PR #25 MERGED(rebase). main `d666aec`** — walk-up 4커밋 rebase 반영(`dc00c69` W-B 가드 → `f79883f` walk-up feat → `3f1e472` R1 fix(to_string_lossy &Path화+테스트) → `d666aec` R2 하드닝(depth 경계+symlink 외부repo 계약)). **머지 후 main 게이트 그린(341 lib + 15 oneline = 356, 0 failed), 버전 0.6.0 불변(미릴리스 — 출하 시 v0.7.0).** 블로커 답 = lterm은 cd 미추적·git 미인지 → **W-B 기각**. 정정: 원래 문제는 **P1(repo 하위 dir 시작)**이고 정답은 **understatus FP-free walk-up(W-A v2)** → **구현·검증·리뷰·머지 완료(always-on, depth 64)**.

### 결론 — 블로커 해소 + verdict 정정 (P1/P2 구분), confidence high
**블로커 답(adversarial 검증 완료):** lterm은 셸 `cd`를 추적하지 않으며 `git_worktree`를 전혀 도출하지 않는다.
- `Session.cwd`는 **비-Mutex 불변 String**(server.rs:274) — `create_session`(server.rs:1800-1807)에서 `-c`/데몬 current_dir로 **1회 캡처 후 영구 고정**. OSC 7/1337 파싱·`/proc`·`proc_pidinfo(PROC_PIDVNODEPATHINFO)` cwd 폴링·cwd 갱신 RPC **모두 production 전무**. `info()`는 매 tick `self.cwd.clone()`(server.rs:408)로 frozen 값 복제. lterm에 git 인지 0건.
- **W-B(payload에 git_worktree 추가) 기각(확정)**: frozen 시작-dir cwd와 동일 부정확성 공유 → FP를 빈 pill(관측 가능) 대신 외부 repo 틀린 branch(관측 불가)로 **displace**할 뿐. → `claude.rs` 주석 가드(PR #25).
- ⚠️ **synthesis verdict 정정 — 문제는 둘로 갈린다**:
  - **P1(높은 빈도, 원래 명시된 문제) → ✅ 구현 완료(PR #25)**: codex가 **repo 하위 dir에서 시작** → `<cwd>/.git` 없음 → branch 미탐. cwd는 **시작 시점엔 정확**하므로 그 위 walk-up은 stale 문제 없이 repo 루트를 올바르게 도출 → **understatus FP-free 디렉터리 체인 walk-up(W-A v2) 구현**. synthesis가 "stale cwd"를 이유로 W-A를 기각한 건 P2 논거를 P1에 잘못 적용한 over-reject였음. W-A의 진짜 비용(FP-free 부모 체인 canonicalize 보안 가드)은 3대 불변식 + 적대검증으로 해소. understatus 단독·lterm 무변경.
  - **P2(낮은 빈도, 미구현)**: 세션 중 codex/셸이 **cd로 이동** → frozen cwd stale → 틀린 branch. 해결 = lterm live cwd(W-B-conditional). codex는 자기 프로세스를 chdir 안 해 드묾. P1 walk-up과 합성 가능(lterm이 live cwd 주면 walk-up이 그 위에서 수혜).
- **W-B-conditional(P2) = 미래 옵션**: lterm이 `proc_pidinfo(PROC_PIDVNODEPATHINFO)` leader-PID live cwd 도출을 **먼저 구현**(cost=medium, lterm 측 별도 OS 종속 작업)해야 진입. M-2(절대경로 가드)는 PR #23으로 이미 충족.

### ✅ 이번 세션 산출물
1. **조사 워크플로(ultracode)**: lterm 4각도 병렬 조사(cwd 생애주기 / cd 추적 feasibility / payload 스키마+git 인지 / understatus 소비측) → 중심 주장 3렌즈 적대적 반증(escape-sequence=confirmed, data-flow=confirmed, proc-syscall=uncertain\*) → synthesis verdict. 8 에이전트, 전부 file:line 증거 기반.
   - \*proc-syscall uncertain은 "lterm이 live cwd를 *줄 수 없다*"는 강한 추론만 반증 — 그건 lterm 측 medium 신규 작업이지 무변경 W-B를 구제하지 않음. cwd-only 우위 불변.
2. **`claude.rs` 주석 가드**(`parse_lterm_input`, behavior 0): "W-B 미채택" 근거를 코드에 박아 후속 기여자가 `RawLtermInput`에 `git_worktree`를 무심코 추가하는 회귀 차단. 기존 W-A 배제 경고(`claude.rs:442-453`)와 동일 패턴.
3. **계획 문서 종결**: `.omc/plans/open-questions.md` 블로커 `[x]` + M-2 `[x]`(PR #23 해결 확인) 기록(gitignored 로컬).
4. **M-2 종결 확인**: `derive_git_branch` ↔ `derive_git_branch_from_cwd` 절대성 가드 대칭, 회귀 테스트 `git_worktree_relative_path_rejected` 고정. 추가 작업 불필요.
5. **P1 walk-up 설계 합의(ultracode)**: 3 설계안(재사용/보안/엣지케이스 우선) → Architect+Critic 적대검토 → 합의 플랜. **Critic의 FP 공격(symlink cwd / linked-worktree gitfile / depth / TOCTOU) 전부 차단·임의 read 0·블로킹 0**. 핵심 footgun 적발: 정지 분기에 `lstat.is_dir()` 쓰면 심볼릭 `.git` 디렉터리(표준 git)가 회귀 → **무분기 reader 위임**으로 차단.
6. **P1 walk-up 구현(PR #25 커밋 `786271b`, feat)**: `derive_git_branch_from_cwd` cwd-only → walk-up. 신규 `find_git_root_dir`/`find_git_root_dir_capped` + `MAX_WALK_UP_DEPTH=64`. **3대 불변식**: ①canonicalize 1회(루프 前) ②probe-then-read 무분기(첫 `.git` 정지) ③depth cap. `read_branch_from_git_dir` 등 무수정 재사용, `derive_git_branch`(Claude 경로) 무변경, Task3 gitfile FN 보존. always-on(의미변화=git-consistent 정탐, 문서화). 주석 5곳 개정("부모 상승 금지"→"3 불변식 유지").
7. **구현 리뷰(독립, author/review 분리)**: correctness/security/test-adequacy 3관점 → verdict **ship**. test-adequacy가 잡은 medium(symlink 테스트 vacuous) 반영 → 테스트를 mutation-저항형으로 재작성(lexical 부모에 함정 repo). **canonicalize 임시 제거 mutation으로 `Some("leaked")` 실패 실증 후 복원** → 불변식① 실제 고정 증명. 신규 8 유닛 + 1 e2e, 기존 회귀 11종 무수정 통과.

### ⏭ Next Steps
> **P1 walk-up = 구현·리뷰·머지 완료(PR #25 MERGED, main `d666aec`).** understatus 이 레포 backlog 사실상 소진.
1. ~~PR #25 머지~~ ✅ **완료**(rebase-merge). **(선택) v0.7.0 릴리스**: walk-up은 사용자-대면 feature(repo 하위 dir에서 git branch 표시)라 출하하려면 minor bump 권장 — §C 절차(3종 버전 범프→태그→release.yml→crates.io→Homebrew prebuilt→npm passkey). 미릴리스 시 main에만 존재.
2. **[선택·부 트랙] P2 = lterm live-cwd(W-B-conditional)**: 세션 중 cd 추적. `Session::info()`(server.rs:408)에서 `self.process_id`로 `proc_pidinfo(PROC_PIDVNODEPATHINFO)` 호출해 cwd live화(payload 스키마 변경 0). codex는 chdir 안 해 빈도 낮음 — value 먼저 ralplan 권장. **lterm이 live cwd를 주면 understatus walk-up이 그 위에서 자동 수혜**(P1+P2 합성).
3. **lterm 최대 가치(불변)**: iTerm OSC1337 백엔드(NativeChrome) 실렌더(대, 미구현). 그 외 TOML `[status]` config, 다중 에이전트 세그먼트, lterm 잔여 LOW(§0·PREV 이하).

---

## §0·NOW-1. 직전 세션 (2026-06-12) — git pill 아이콘 수정 + 잔여 backlog Goal 완주

> **Goal**: git pill 아이콘 글리프 미표시 수정 후, understatus 잔여 backlog를 `/goal`로 연속 처리(각 Task: **ralplan 합의 → executor 구현 → quad-review-loop → rebase-merge**). 4개 PR 전부 머지.
>
> **현재 상태: 전부 완료·머지, 열린 PR 0, main `558aafb`(+이후 HANDOFF 갱신), test 342(328 lib + 14 oneline) 그린, 버전 0.6.0 불변(내부 hardening·테스트라 범프 불요).** understatus 이 레포 내 "지금 가능한" backlog는 **사실상 소진** — 남은 건 walk-up 하나뿐이고 그건 lterm 조사 선결로 블로킹.

### ✅ Current Progress (이번 세션 머지분, 시간순)
1. **git pill 아이콘 SF Symbol 수정** (PR #21 `fix(render)`, 머지 `7511a74`): 06-10에 추가된 git pill의 `icon: Some("git-branch")`가 cmux 사이드바에 **글리프 없이 주황 텍스트만** 뜨던 문제. **근본 원인 = cmux `--icon`은 SF Symbol 이름을 직접 렌더**한다(cmux 바이너리 `/Applications/cmux.app/Contents/Resources/bin/cmux` 내 `toolIcon` 함수 주석 `// SF Symbol names rendered inside the cmux status badge`, 매핑값 eye/pencil/terminal/sparkles/globe/checklist 전부 SF Symbol — `strings` 추출로 확정). `git-branch`(Lucide/nerd-font명)는 SF Symbol이 아니라 drop된 것. → **`arrow.triangle.branch`**(git 브랜치 표준 SF Symbol)로 교체. `render.rs:337` + 테스트 단언 + 주석. **라이브 cmux 사이드바 글리프 육안 확인**(사용자). model pill의 `sparkles`(✨)가 known-good 대조군.
2. **Task 1 — git-branch pill 견고화** (PR #22, 머지 `d90d031`/`70684ab`/`42a9cb1`/`13dac4c`): quad-review 잔여 LOW 묶음 + 리뷰 LOW.
   - **branch byte cap** `MAX_BRANCH_LEN=256`(claude.rs `read_branch_from_git_dir` chokepoint, byte `.len()`): 256B 초과=손상/조작 `.git/HEAD` 신호 → None(FP<FN). NAME_MAX=255라 정상 branch는 초과 불가.
   - **테스트 RAII guard**: `unique_test_dir`를 `TestDir`(`Drop`=remove_dir_all + `Deref<Path>` + `AsRef<Path>`) 반환형으로 승격 → panic 시 temp 누수 0. 구식 PID-only 3곳(collision 위험) 통일. `catch_unwind` panic-safe 증명 테스트.
   - **교차-pill SF Symbol 계약 테스트** `cmux_pill_icons_contain_no_hyphen`: 모든 pill icon에 하이픈 부재(SF Symbol은 점·소문자, 하이픈=Lucide=cmux drop) → `git-branch` 회귀 영구 차단. + vacuous-pass 가드(pill 비어있음·icon 전부 None 차단).
   - symlink `.git` 추종 의도 테스트 + 동기 fs read 트레이드오프 doc(비파괴).
3. **Task 2 — M-2 절대경로 가드 대칭화** (PR #23, 머지 `c9241fc`): `derive_git_branch`(Claude workspace `git_worktree`/`repo` 경로)에 `is_absolute()` 가드가 **없어** 상대경로(`"repo"`/`"."`)가 프로세스 cwd 기준 해석돼 엉뚱한 repo branch FP였음(canonicalize cwd-상대). `derive_git_branch_from_cwd`(lterm cwd)는 이미 가드 보유 → **대칭화**. **ralplan: Planner=B(공유 헬퍼에 흡수) vs Architect/Critic=A(개별 추가)** — B는 `is_safe_base_path` 공개 계약(doc "절대 허용") 반전 + SRP 위반이라 A 채택, 공유 헬퍼 불변. host-독립 단위 테스트(`derive_git_branch` 직접 호출).
4. **Task 3 — linked worktree gitfile = No-go 확정 + FN 회귀 가드** (PR #24, 머지 `1527275`/`558aafb`): linked worktree·서브모듈은 `<base>/.git`가 `gitdir:` **정규 파일**(현재 `<base>/.git/HEAD` ENOTDIR → None = 안전 FN). **ralplan 합의 = No-go**(구현 안 함). **근거 = feasibility**(value 미측정 아님): Architect가 `git worktree add` **실증** → 표준 worktree·서브모듈의 실제 HEAD는 **항상 `<base>` 밖**(main repo 하위) → 보수적 추종(C: `<base>` 경계)은 **0% 커버** = value 0 + 새 공격면 = 순손실; 전체 추종(A)은 임의 위치 파일 read primitive 개방. **산출물 = 프로덕션 로직 0**, 현 안전 FN을 **mutation-resistant 회귀 테스트**로 고정(gitdir 타깃 실재화 + sentinel HEAD → 추종 구현 시 `Some(sentinel)`로 None 단언이 깨져 회귀 포착) + doc 강화(ENOTDIR·서브모듈 명시).

### ✅ What Worked
- **`/goal` × (ralplan → executor → quad-review-loop → 머지) 사이클** 4회 반복 — 안정적. 각 Task가 독립 PR·CI 그린·atomic 커밋.
- **멀티에이전트가 실재 결함을 잡음**: Task1 Critic이 약한 단언(C1)·site 오기(C2) 적발; Task2 Architect/Critic이 Planner의 B를 "공개 계약 반전 비용"으로 뒤집고 A 확정; Task3 Architect가 `git worktree` **실증**으로 (C) 0% 커버 증명; **Task3 quad-review-loop가 round 1에서 3트랙 합의 blocker**(테스트 mutation 저항 없음 — gitdir 타깃 비존재) 적발 → round 2 sentinel 실재화로 해소·수렴.
- **cmux 아이콘 어휘를 코드로 확정**: 라이브 시행착오 프로빙 대신 cmux 바이너리 `strings`에서 `toolIcon`(SF Symbol 매핑) 발견 → 단일 후보로 수렴. 블랙박스를 코드 증거로 깸.
- **매 executor 산출물을 rustup 게이트로 독립 재검증**(author/review 분리). IDE phantom 진단(`fs.rs` E0277 등)을 `cargo test` 통과로 반증.

### ⚠️ What Didn't Work / 주의 (반복 회피)
- **executor가 커밋을 누락한 사례**(Task3 blocker fix): 보고가 cut off되며 working tree만 수정하고 커밋 안 함 → 오케스트레이터가 직접 커밋. **executor 자기보고 비신뢰 — 매 단계 `git log`/게이트로 실제 상태 확인.**
- **agy(Antigravity)는 review 프롬프트에서 4라운드 연속 hang**(타임아웃 래퍼 없이 띄우면 프로세스 방치 → pkill 필요). 핸드오프 known issue. **Forge는 라운드별 가변**(PR#21 token-mismatch 폐기, PR#23/#24 정상). → Claude+Codex 안정 듀얼 + Forge 보조로 합의.
- **quad-review-loop blocker 기준** = severity HIGH+ AND consensus(≥2 트랙). Task3에서 Codex HIGH + Forge Major + Claude MEDIUM = 합의 blocker로 정확히 정지·수정.
- IDE/rust-analyzer phantom: `TestDir`의 `Deref`-not-`AsRef`에 막혀 `fs.rs` create_dir_all/remove_dir_all 가짜 진단 → rustup clippy 클린으로 반증(메모리 `rust-toolchain-broken`).

### ⏭ Next Steps — 남은 로드맵 (understatus 이 레포)
> **이 레포 "지금 가능한" backlog는 소진.** 아래 1개만 남았고 블로킹.
1. ~~**walk-up branch 도출**(중, 블로킹)~~ ✅ **§0·NOW(06-13)에서 해소**: lterm 조사로 블로커 답 확정(lterm은 cd 미추적·git_worktree 미도출) → verdict = **cwd-only(walk-up No-go)**. W-B/W-A 모두 기각, W-B-conditional은 lterm 측 live cwd 구현 선결. 상세는 §0·NOW.
2. ~~git pill 아이콘~~ ✅ PR#21. ~~M-2 가드~~ ✅ PR#23. ~~linked worktree gitfile~~ ✅ PR#24(No-go+가드). ~~quad-review 잔여 LOW·하이픈 가드~~ ✅ PR#22.

**lterm (`/Users/jinhongan/Desktop/light_terminal`, 별도 레포 · Phase 2 — spec §15):** 변동 없음. 최대 가치 = **iTerm OSC1337 백엔드(NativeChrome) 실렌더**(대, 미구현). 그 외 TOML `[status]` config, 다중 에이전트 세그먼트, lterm 잔여 LOW. 상세는 §0·PREV 이하 참조.

---

## §0·PREV. 직전 세션 (2026-06-11) — 릴리스 + 설치 하위호환 + ctx 튜닝 + node24

> **Goal**: understatus(+lterm) statusline 제품을 출하·유지보수. 이번 세션은 누적분 릴리스 + 설치 진입장벽 제거 + ctx 정확도 튜닝.
>
> **현재 상태: 전부 완료·라이브, 블로킹 0, 열린 PR 0, main `d499ad8` + 이후 HANDOFF 갱신.** understatus **v0.6.0가 4채널(crates.io·GitHub Release·Homebrew·npm) 전부 라이브**.

### ✅ Current Progress (이번 세션 처리분, 전부 머지·배포)
1. **v0.5.0 릴리스**(4채널) — 06-10 git pill + cmux pills 누적분. PR #15/#16, 태그 v0.5.0(`29ca989`). 상세는 아래 §0 블록쿼트.
2. **GHA Node20 deprecation 대응**(PR #17 `2587ce7`): `actions/checkout@v4→v6`, `softprops/action-gh-release@v2→v3`(둘 다 node24). `dtolnay/rust-toolchain`은 composite라 무변경. ci.yml이 PR CI에서 checkout@v6 실검증.
3. **설치 CLT 26.3 요구 제거 = Homebrew formula prebuilt 전환**(PR #18 `f912aea` + tap `c839a47`→`99b2fb6`): `depends_on "rust"`+`cargo install`(소스 컴파일) → `on_arm`/`on_intel` url+sha256+`bin.install`(다운로드만). **컴파일 없어 CLT 불필요**(공식문서 확인). 배포 바이너리 `minos 11.0`→macOS 11+ 실행. `brew install` 2초·컴파일0 실측. `cargo install`만 본질상 소스라 CLT 필요(README가 brew/npm을 CLT-free로 안내).
4. **ctx 튜닝 = hold 상수 2개 `[context]` config 노출**(PR #19 feat `10d8ecc`+bump `ce298e0`): `hold_ttl_seconds`(기본 **600→180**, 반응성↑/stale↓, 0=비활성) + `drop_tolerance`(기본 **12.0 불변**, 12 미만은 86↔98 깜빡임 위험). 배선 `resolve_claude_context(&cfg.context)`→`read_held_native_ctx(ttl)`/`resolve_context_percent(drop_tolerance)`, 기본값 `DEFAULT_CONTEXT_*` pub 상수 단일출처. config.rs/claude.rs/main.rs, 동작은 TTL 외 동일. executor(opus) 구현, rustup 실측 **321+14=335 테스트** 그린.
5. **v0.6.0 릴리스**(4채널) — 태그 v0.6.0(`ce298e0`). crates.io v0.6.0 · GitHub Release(arm64 `c9116944…`/x64 `febcd0f1…`) · Homebrew prebuilt v0.6.0(`99b2fb6`, 사본 PR #20 `d499ad8`) · npm `understatus@0.6.0`(latest, 레지스트리 클린설치 E2E 통과). **릴리스 절차는 §C(prebuilt 방식으로 갱신됨) 참조.**

### ✅ What Worked
- **릴리스 스킬 + §C 절차 + PR rebase-merge 파이프라인** 반복 — 안정적. 각 단계 **E2E 실측**(brew install "2초", npm registry 클린설치, otool `minos 11.0`, cargo dry-run)으로 자기보고 대신 증거 확보.
- **prebuilt formula 전환**이 CLT 요구를 근본 제거(소스 컴파일 제거) — document-specialist로 Homebrew 공식문서 사실관계 확인 후 적용.
- **executor(opus)에 정밀 스펙 위임 → rustup 실측 4게이트로 독립 검증**(author/review 분리). IDE phantom 진단을 cargo test 통과로 반증.

### ⚠️ What Didn't Work / 주의 (반복 회피)
- **gh GraphQL 세션 중 간헐 401 / connection reset** → **재시도 루프**로 우회(`gh pr create/merge`, `gh pr checks --watch`도 영향). REST `gh run view` 폴링이 더 안정적. **git push는 osxkeychain이라 무영향.** 만성화 시 `gh auth refresh -h github.com`(브라우저=사용자).
- **IDE/rust-analyzer 인자불일치(E0107/E0061) phantom 진단** — 깨진 Homebrew 툴체인 탓. **오직 rustup `cargo test/clippy`만 신뢰**(메모리 `rust-toolchain-broken`).
- **`cargo install`(crates.io)은 본질상 소스 컴파일** → CLT 계속 필요. brew/npm만 CLT-free.
- **npm publish는 항상 사용자 passkey(EOTP)** — 에이전트 불가. 매 릴리스 마지막 수동 단계.
- **`brew style` advisory**: 과거 desc 82자(>80) — prebuilt 재작성 때 71자로 트림해 해소. `depends_on`은 `on_macos`보다 앞.

### ⏭ Next Steps — 남은 로드맵 (전부 **선택**, 블로킹 0)
> understatus 열린 이슈 0, v0.6.0 라이브. lterm도 현재(v1.0.23). 아래는 "있으면 좋은" 폴리시·확장.

**understatus (이 레포):**
1. **git pill 아이콘**(소): cmux 지원 아이콘명 조사 → git pill 아이콘 부착(현재 주황 텍스트만, cmux가 `git-branch` 미지원해 drop). model의 `sparkles`(✨)는 지원됨.
2. **v2 false-positive-free walk-up**(중): codex가 repo 하위 dir 시작 시 branch 도출(현재 cwd-only). 안전한 walk-up(`base_path` 디렉터리 canonicalize로 repo 경계 확인) 또는 lterm payload `git_worktree` 추가. — §0 이월 #3 참조.
3. **quad-review 잔여 LOW**(소, 비차단): (a) branch명 길이 cap (b) symlinked `<cwd>/.git`→other-repo HEAD 누출 의도 테스트/문서화 (c) 동기 fs read 지연(느린 마운트) (d) 테스트 dir RAII cleanup. — §0 이월 #4.
4. **linked worktree gitfile**(소): `.git`이 파일(워크트리)인 경우 지원(현재 표준 워크트리만).
5. ~~cost pill~~ — **구조적 불가**(codex rollout JSONL에 cost 필드 없음). 로드맵 제외 확정.

**lterm (`/Users/jinhongan/Desktop/light_terminal`, Phase 2 — spec §15):**
6. **iTerm OSC1337 백엔드(NativeChrome)**(대): cmux 없는 iTerm 사용자용 status. 라우팅 PoC 머지됨, 실렌더 미구현. base64 인코딩 필수(`protocol.rs:309` pub 승격), `detect_is_iterm` 이미 존재. `.poc/poc2-iterm-status.sh`가 검증법. **남은 것 중 최대 기능 가치.**
7. **TOML `[status]` config + `lterm attach --status-command` CLI 플래그**(중): 현재 env-only. lterm에 config 로더·`toml` 의존 신설 필요.
8. **다중 에이전트 세그먼트**(중): Gemini/OpenCode 등 전용 표시.
9. **lterm 잔여 LOW**(소): `build_status_payload`가 daemon `info.agent_name` 우선 사용, reader 스레드 group-kill(`kill(-pgid)`, libc 의존), status row 테마 bg 옵션화 등. — §B-6.

---

## §0. 직전 세션 (2026-06-10) — lterm 경로 git branch pill (구현·검증·라이브·quad-review-loop·**머지 완료**) + v0.5.0/v0.6.0 릴리스 상세

> 이번 세션: cmux pills 후속 트랙(§0A 이월 #3(b) "cost·git payload 확장")을 ralplan 합의로 **스코프 재정의**해 구현 → 라이브 검증 → **quad-review-loop**로 실재 보안 blocker 1건 수정 → **PR #14 머지**. lterm 경로(`--source lterm --surface-format cmux-status`)의 cmux 사이드바에 **git branch pill 추가**. **understatus 단독 변경**(lterm 무변경).
>
> **현재 상태: PR #14 MERGED(main `4baf1c5` feat + `21f83e8` fix, rebase), 열린 PR 0, CI 그린, 라이브 cmux 검증 통과, feature 브랜치 정리됨.**
>
> **✅ 릴리스 완료 (2026-06-11): understatus v0.5.0 4채널 전부 라이브.** PR #15(버전 범프, rebase-merge `29ca989`) + PR #16(homebrew 사본 동기화 `1569466`). 태그 v0.5.0(`29ca989`). 채널: **crates.io v0.5.0** · **GitHub Release v0.5.0**(arm64+x64 tar.gz+sha256) · **Homebrew tap `ictechgy/homebrew-understatus`**(commit `ffc292a`, 소스 아카이브 sha256 `4fe6384c…`, `brew info`가 stable 0.5.0 인식) · **npm `understatus@0.5.0`**(latest 태그, 사용자가 passkey로 publish; 레지스트리 클린설치 E2E 통과 — install.js가 v0.5.0 바이너리 SHA-256 검증·수신·`understatus 0.5.0` 실행 확인). 4게이트 그린(318+14=332 테스트). gh GraphQL이 세션 중 간헐 401(토큰 flaky) → 재시도로 통과, git push는 osxkeychain으로 무영향.
>
> **✅ 후속 세션 (2026-06-11, 같은 날): v0.6.0 릴리스 + 설치 하위호환 + Node24 액션 + ctx 튜닝.** 4건:
> 1. **GHA Node20 deprecation 대응**(PR #17, `2587ce7`): `actions/checkout@v4→v6`, `softprops/action-gh-release@v2→v3`(둘 다 node24). `dtolnay/rust-toolchain`은 composite라 무변경. ci.yml이 PR에서 checkout@v6 실검증.
> 2. **설치 CLT 26.3 요구 제거 = Homebrew formula를 prebuilt 바이너리로 전환**(PR #18 `f912aea` + tap `c839a47`→이후 `99b2fb6`): `depends_on "rust"`+`cargo install`(소스 컴파일) → `on_arm`/`on_intel` url+sha256+`bin.install`(다운로드만). **컴파일 없어 CLT 불필요**(공식 문서 확인). 배포 바이너리는 `minos 11.0`이라 macOS 11+ 실행(otool). `brew install` 2초·컴파일0 실측. **`cargo install`만 본질상 소스 컴파일이라 CLT 필요**(README에 명시, brew/npm을 CLT-free 경로로 안내). README Install 섹션 갱신.
> 3. **ctx 튜닝 = hold 상수 2개를 `[context]` config로 노출**(PR #19 feat `10d8ecc`+bump `ce298e0`): `hold_ttl_seconds`(기본 **600→180**, 반응성↑/stale↓, native 누락 시 직전값 유지 시간, 0=비활성) + `drop_tolerance`(기본 **12.0 불변**, hold 해제 하강 임계치 %p, 12 미만은 86↔98 깜빡임 위험). 배선: `resolve_claude_context(&cfg.context)`→`read_held_native_ctx(ttl)`/`resolve_context_percent(drop_tolerance)`, 기본값 `DEFAULT_CONTEXT_*` pub 상수 단일출처. config.rs/claude.rs/main.rs, **동작은 TTL 기본 600→180 외 동일**. executor(opus) 구현, rustup 실측 4게이트 그린(**321+14=335 테스트**). ⚠️ IDE가 표시한 인자불일치(claude.rs/main.rs)는 **깨진 Homebrew 툴체인의 phantom** — rustup `cargo test` 통과로 반증(메모리 `rust-toolchain-broken` 재확인).
> 4. **v0.6.0 4채널 릴리스 — 전부 라이브 ✅**: 태그 v0.6.0(`ce298e0`). **crates.io v0.6.0** · **GitHub Release v0.6.0**(arm64 sha256 `c9116944…`, x64 `febcd0f1…`) · **Homebrew tap prebuilt v0.6.0**(`99b2fb6`, repo 사본 PR #20 `d499ad8`, `brew info`=stable 0.6.0, 2초 설치 실측) · **npm `understatus@0.6.0`**(latest 태그, 사용자가 passkey로 publish; 레지스트리 클린설치 E2E 통과 — v0.6.0 바이너리 SHA-256 수신·`understatus 0.6.0` 실행 확인).

### quad-review-loop 결과 (2라운드 수렴)
- **R1 blocker(2/3 합의, 수정됨)**: `read_branch_from_git_dir`이 신뢰 불가 `.git/HEAD` 내용(악성 repo의 `ref: refs/heads/main␛[31m…`)을 검증 없이 반환 → oneline SGR/cmux pill 터미널 인젝션. **`char::is_control` 거부**로 source chokepoint에서 차단(lterm+Claude 경로 동시). 동반: 상대경로 cwd 거부(절대경로 요구), 고정경로 테스트 hermetic화. commit `21f83e8`.
- **R2 수렴**: Codex APPROVE. Claude 유일 HIGH(pill value 셸 메타문자 인젝션)는 **lterm sink가 `cmd.arg(value)` 셸 미경유(tmux_compat.rs)임을 코드로 확인 → false-positive 확정**(기존 model/cpu/mem pill과 동일 sink, 이 PR 도입 아님). consensus blocker 0.
- **교훈**: ralplan은 path traversal만 봤고 **content 살균(제어문자)을 놓침** → quad-review가 실재 보안 갭을 메움. 반대로 단일트랙 HIGH는 교차레포 코드 검증으로 false-positive를 걸러 불필요 수정 회피. Forge는 R2에서 reasoning-only 출력으로 폐기(flaky), Antigravity는 21~28KB 프롬프트 hang으로 양 라운드 SKIP → 사실상 Claude+Codex 듀얼.

### 핵심 발견 / 결정 (다음 세션이 알아야 할 것)
- **cost 영구 제외(데이터 소스 부재)**: codex rollout JSONL에 **cost 필드 자체가 없음**(understatus `codex.rs` CodexExtras/TokenSnapshot은 rate-limit %·plan·effort만). lterm은 PTY 래퍼라 자식(codex) 내부 cost 미접근. → "cost·git payload 확장"의 **cost는 구조적 불가**. git만 진행.
- **git은 understatus 단독으로 실현(lterm payload 확장 불필요)**: lterm이 이미 보내는 `cwd`로 understatus가 직접 `.git/HEAD`를 읽으면 됨. lterm `SessionInfo.cwd`는 세션 시작 dir(셸 cd 추적 안 됨)이나 codex는 보통 repo 루트 고정이라 실용상 OK(수용 한계).
- **cwd-only 채택, 부모 walk-up 기각(Architect 적발)**: walk-up은 `read_branch_from_git_dir`의 canonicalize가 `<base>/.git/HEAD` **파일만** 보호하고 디렉터리 체인은 검증 못 해, 심볼릭 cwd에서 **타 repo branch를 확신 표시하는 false-positive(오정보)** 위험. status 표면에선 빈 pill(false-negative) ≪ 틀린 pill. → cwd-only(`<cwd>/.git/HEAD` 1회)만, 정탐률 보완은 v2 이월.
- **Q4 코드 확정**: lterm `is_valid_pill_key("git")`==true(`tmux_compat.rs:1673` ref-segment `[A-Za-z0-9_-]` + `:3999` len≤64). lterm sink가 "git" 키를 제네릭 set-status → **lterm 변경 불필요 전제 성립**.
- **cmux 네이티브 branch 표시 발견(라이브)**: cmux가 워크스페이스마다 `branch • cwd` 줄을 **자체 표시**(우리 pill엔 cwd 없음). 단 **다른 세션에선 누락되기도 함**(불안정) → 우리 pill이 일관된 폴백으로 별개 가치. 사용자가 유지 결정.
- **git-branch 아이콘 drop(R4 예측대로)**: cmux가 `git-branch` 아이콘명 미지원 → 아이콘 누락(주황 텍스트는 정상 렌더). model의 `sparkles`(✨)는 지원. 아이콘 띄우려면 cmux 지원 아이콘명 조사 필요(폴리시 follow-up).

### ✅ 완료 (feature 브랜치, PR #14)
- **claude.rs**: `derive_git_branch_from_cwd(cwd: &str) -> Option<String>` 신규(cwd-only, `is_safe_base_path`+`read_branch_from_git_dir` 재사용, **부모 walk-up 없음** — doc에 v2 이월 명시). `parse_lterm_input`이 `cwd.as_deref().and_then(derive_git_branch_from_cwd)`로 도출(기존 영구 None 제거). 거짓 "항상 None" 주석 정정.
- **render.rs**: git 세그먼트 pill화(`key=git`, `value=branch`, `color=#F1502F` `pill_git_color()`, `icon=git-branch`, `priority=40`). `label_value_segment` 시그니처 불변 → oneline 바이트 보존.
- **회귀 0**: 기존 4 pill 키(model/ctx/cpu/mem) 불변, oneline 불변, Claude 경로 무영향, version bump 없음, 신규 의존성 없음.
- **검증**: 4게이트 그린(fmt/clippy -D warnings/test/release --locked). **lib 316 + oneline 14 통과**. AC1-AC9 테스트 실증, Guardrail 위반 0(독립 verifier 재실행). 보안: traversal/외부향 심볼릭 HEAD/detached/.git 부재 → 전부 None(패닉 0).
- **라이브 cmux 검증 통과**: 사이드바 `더 보기` 펼치면 `feature/lterm-git-branch-pill` git pill 주황(#F1502F) 렌더 확인(사용자 육안). 아이콘만 drop(무해).

### 워크플로 / 교훈
- brainstorming 없이 바로 ralplan(후속 트랙 택1) → explore×2(양 레포 payload 파이프라인) → ralplan 합의(Planner→Architect→Critic **3라운드**, APPROVE) → executor(opus) 구현 → verifier(sonnet) **독립 게이트 재실행** → 라이브 육안.
- **멀티에이전트가 단일 리뷰 사각을 메움**: ① Architect가 walk-up의 보안 false-positive(심볼릭 cwd→타 repo) 적발 → Option 1로 전환. ② Critic 라운드2가 `sample_input`(render.rs:799 `git_branch:Some("main")`) 기반 **render.rs 테스트 3개 깨짐** + claude.rs lterm 테스트 4개 **거짓 계약화**(주석 "항상 None"이 T2 후 거짓) 적발 → T4-a/T4-e로 처리. Planner 단독으론 전부 누락.
- **"cost·git payload 확장" 프레이밍이 코드와 불일치**: explore가 cost 데이터 소스 부재 + git은 lterm 변경 불필요를 밝혀 스코프를 git-only·understatus-only로 재정의. **HANDOFF 이월 항목도 코드로 재검증 필요**.

### ⏭ 다음 세션 이월
1. ~~**understatus 릴리스**~~ ✅ **완료(2026-06-11, v0.5.0)** — crates.io·GitHub Release·Homebrew tap·npm 4채널 전부 라이브. 상세는 위 §0 "릴리스 완료" 줄.
2. **git-branch 아이콘 폴리시**(선택): cmux 지원 아이콘명 조사해 git pill에 아이콘 부착(현재 주황 텍스트만 — cmux가 `git-branch` 미지원해 drop, R4).
3. **v2 false-positive-free walk-up**(선택): `base_path` 디렉터리를 canonicalize해 repo 경계 확인하는 안전한 walk-up → codex가 repo 하위 dir 시작 시도 branch 도출. 또는 lterm payload에 `git_worktree` 추가.
4. **quad-review 잔여 MEDIUM/LOW**(비차단, 추적): (a) branch명 길이 cap(source defense-in-depth — 단 lterm `cap_field`가 다운스트림 절단). (b) symlinked `<cwd>/.git`→other-repo HEAD 누출(`.git` 심볼릭 추종은 표준 git 동작이라 과수정 위험 — 문서화/의도 테스트 권장). (c) 동기 fs read 지연(느린 마운트 cwd). (d) `unique_test_dir` 교차-run cleanup(RAII).
5. **linked worktree gitfile**(`.git`이 파일) 지원(현재 표준 워크트리만).
6. 설계/계획 문서: `.omc/plans/lterm-git-branch-pill.md`(ralplan 합의 확정본, ADR 포함 — **단 `.omc`는 gitignored 로컬**). quad-review-loop 레저: `~/.claude/logs/quad-review-loop/ictechgy-understatus-14-*.md`.

### 검증 수치
- understatus main(머지 후): clippy `-D warnings` 클린, **318(lib) + 14(oneline) = 332 테스트** 통과, release `--locked` 빌드 클린, CI 그린. (구현 시점 316 → quad-review 보안수정으로 신규 테스트 +2 = 318.)

---

## §0A. 직전 세션 (2026-06-09) — cmux 네이티브 status pills 실렌더 (완료/머지)

> 이번 세션: lterm-in-cmux의 codex status를 **DECSTBM 인라인 행 대신 cmux 네이티브 사이드바 pill(`set-status`)**로 렌더하는 실렌더 트랙. §0A(06-08)의 "다음 세션 이월 = lterm 실렌더 트랙"을 완수. understatus **PR #13** + lterm **PR #123** 둘 다 머지.
>
> **현재 상태: 열린 PR 0, 양 레포 main 머지·CI 그린, 라이브 cmux 검증 통과.** 양쪽 **미릴리스**(understatus v0.4.0 / lterm v1.0.22 이후 누적 — 릴리스하려면 §C 절차).

### 핵심 발견 (다음 세션이 알아야 할 것)
- **cmux 네이티브 status API 존재**: `cmux set-status <key> <value> [--icon][--color #hex][--priority]` → 좌측 사이드바 워크스페이스 항목에 pill 렌더. `clear-status`/`list-status` 동작. HANDOFF가 몰랐던 경로(과거 "write 핸들 없음"으로 오판). **`cmux send`는 키보드 입력 주입이지 화면 페인트 아님** → split 렌더러 대신 set-status 채택.
- **`set-progress`는 워크스페이스 전역**(pane-keyed 아님) + `list-progress` 부재 → SIGKILL 시 stale progress 청소 불가(누수). **진행바 채택했다가 quad-review에서 제거, ctx는 pill만.**
- **워크스페이스 식별 함정**: `$CMUX_WORKSPACE_ID` env는 lterm 세션에서 stale(죽은 ws). runtime `cmux identify` focused는 포커스 드리프트 → **attach 시점 `cmux identify --id-format uuids`로 UUID 캡처**(stored split-time 컨텍스트 우선, `tmux_compat::cmux_status_identity`).
- **codex는 RowOff**(`show_status:false`, attach 경로 `likely_agent_session→RowOff` `main.rs:2258`)라 `requests_row()==false`. cmux pill은 off-grid라 **`sink_enabled`를 `requests_row()`에 묶으면 1차 표적 codex에서 영구 OFF**(Architect R3 BLOCKER). 정답: `sink_enabled = matches(Cmux) && LTERM_STATUS_COMMAND set && !--no-status`; `in_grid = !sink_enabled && backend!=Disabled && requests_row()`(pill 미사용 cmux 셸은 기존 DECSTBM 보존, 회귀 0).

### ✅ 완료 (양쪽 main 머지)
- **understatus #13**(rebase): `--surface-format cmux-status` 출력 모드 — oneline과 동일 `collect_segments` 재사용해 `model·ctx·cpu·mem` pill JSON 방출. `Segment`에 additive `pill: Option<PillMeta>`(oneline 바이트 불변). 색 신규 매핑(cpu만 `band_tint` 재사용). ctx 0..=100 클램프+정수% 양자화. cost·git은 lterm 파서 영구 None(`claude.rs:288-289`)이라 제외. 핵심: `src/render.rs`(to_cmux_pills/PillMeta/color_to_hex), `src/main.rs`(SurfaceFormat/--surface-format). 설계/계획: `docs/superpowers/specs/2026-06-08-cmux-native-status-pills-design.md`, `.../plans/...-plan.md`.
- **lterm #123**(merge): `CmuxStatusSink`(`src/tmux_compat.rs` cmux_status 모듈) — pill JSON diff→`cmux set-status/clear-status` 변경분만. 라우팅 `in_grid`/`sink_enabled` 분리(`client.rs:3096`), 소비점 `client.rs:3421` 분기(StatusBar 미진입, in_grid 경로 바이트 불변), `cmux_status_identity`(UUID), 고아 재조정(attach 시 list-status, 실패 시 best-effort), Drop 청소, 서킷브레이커(3연속 실패→blackout), cmux 호출 **3s 타임아웃**(`run_cmux_command` `wait_with_timeout`), pill key 검증(`is_valid_pill_key`)+value/color/icon cap.
- **라이브 검증 통과**: 실제 `lterm codex`에서 사이드바 pill(cpu/mem/✨codex) 렌더 + **codex 입력칸 무손상**(DECSTBM 제거 = 본 트랙 수용기준) + detach 청소(사용자 육안 확인).

### 워크플로 / 교훈 (반복 회피)
- brainstorming → **cmux API 라이브 탐침**(set-status 발견) → ralplan 합의(Planner×2/Architect×3/Critic×2) → 청크 구현(executor) → **라이브 PTY 검증** → quad-review-loop.
- **Architect R2가 lterm 레포 안 읽고 "앵커 0 hit → UNSOUND" 오발** → 메인 에이전트가 직접 grep해 반증(앵커 전부 실재) 후 R3 재실행. **교차레포 리뷰 시 에이전트에 레포 절대경로 명시 + "신규 식별자는 작성 대상" 프레이밍 필수.**
- **quad-review-loop가 결정적 값**: Claude code-reviewer는 양쪽 APPROVE였으나 **Codex(gpt-5.5)가 lterm HIGH 3건**(① `run_cmux_command` 무한 대기→프리즈 ② pill key 미검증 ③ set-progress 전역 누수) 적발 → 전부 수정. **단일 리뷰 사각을 멀티모델이 메움.**
- **agy는 8KB+ 프롬프트 hang**(92KB diff라 SKIP), **forge는 `forge info`부터 flaky** → quad가 사실상 Claude+Codex 듀얼. 정상 폴백.
- ralplan/quad-review가 코드 사실 불일치를 잡음: "핵심 4 pill(cost·git)"이 codex 경로 구조적 None → model·ctx·cpu·mem로 재결정.

### ⏭ 다음 세션 이월 (전부 선택)
1. **understatus 릴리스**: v0.4.0 이후 cmux pills 누적분 미릴리스. §C 절차(3종 버전 범프→태그→`release.yml` 그린 대기→`cargo publish`→Homebrew tap→npm은 사용자 passkey).
2. **lterm 릴리스**: v1.0.22 이후 미릴리스.
3. **cmux pills 후속**: (a) cmux `rpc` 배치 set으로 `sink.apply` 동기 spawn을 비동기 worker로(현재 3s 타임아웃으로 프리즈만 차단, diff 게이트로 호출 드묾). (b) cost·git용 lterm payload 확장(현재 codex 경로 None). (c) NativeChrome(iTerm OSC1337)·DelegatedSurface(Tmux) 백엔드. (d) 동일 pane 동시 attach 시 짧은 pill 깜빡임(수용 한계, instance-id는 SIGKILL 재조정과 상충해 미도입).

### 검증 수치
- understatus main: clippy 클린, **310+13 테스트**, CI(ci) 그린.
- lterm main: **1.96** clippy 클린, unit **417** + cli_smoke 201, release `--locked`, CI 7체크 그린.

---

## §0B. 직전 세션 (2026-06-08) — 완료(배경)

> 이번 세션: ① understatus **ctx 소멸 버그 수정**(#9) + ② lterm **status 라우팅 인프라 배선**(#122) + ③ **진짜 ctx 소멸 원인 = `workspace.repo` 객체화 파싱 실패 수정**(#10) + ④ **understatus v0.4.0 4채널 배포 완료**. 직전 세션(06-07)은 §0C, 배경은 §A~E.
>
> **현재 상태: 열린 PR 0, understatus v0.4.0 라이브(crates.io·npm·Homebrew·GitHub Release), 화면 ctx 정상.** 다음 작업은 lterm 실렌더 트랙(아래 이월).

### ✅ 완료 (양쪽 main 머지됨)
1. **understatus ctx 소멸 버그 수정** — Claude Code statusline JSON의 `context_window.used_percentage`가 **간헐 누락**되면 understatus가 ctx 세그먼트를 생략하면서 동시에 체인된 omc HUD ctx도 strip(§0C-2)해 **ctx가 화면에서 완전히 사라지던** 버그(스크린샷 증상). 체인된 omc HUD의 자체 안정화는 매 refresh마다 새 프로세스로 떠 인메모리 상태가 초기화돼 86↔98로 튀던 게 strip의 원인. 수정:
   - **토큰 fallback**: `context_window`의 `current_usage` 토큰합/`total_input_tokens` ÷ `context_window_size`(omc HUD `getContextPercent`와 동일 우선순위).
   - **resolve_context_percent**: 양수 native > TTL(30s) 내 직전 native 유지(hold, 세션 캐시 `ctx_native`) > 토큰 fallback > 생략.
   - **비대칭 하강 가드**: 상승 노이즈(86↔98)는 hold로 차단하되, fallback이 직전 native보다 12%p↓이면(`/compact` 등 실감소) hold 해제·즉시 반영. omc 대칭 tolerance가 86↔98 상승에도 튀던 회귀 회피.
   - **held 캐시 신뢰경계**: `interpret_held_native_ctx`가 `0<v≤100` 유한값만 인정(변조 캐시 거부→fallback 저하). **lenient f64 역직렬화**: 토큰 필드 타입 드리프트가 statusline 전체를 무력화하지 않게 격리.
   - → **understatus PR #9 머지**(main `a9368bf`, 커밋 4개). **quad-review-loop 2라운드**(Codex+Forge 2트랙 합의 MEDIUM=held 검증 반영). **297 테스트**.
   - 핵심 파일: `src/claude.rs`(compute_context_fallback/percent_of/clamp_percent/resolve_context_percent/ContextResolution/deserialize_lenient_f64), `src/main.rs`(resolve_claude_context/interpret_held_native_ctx, `CONTEXT_HOLD_TTL_SECONDS=30`/`CONTEXT_HOLD_DROP_TOLERANCE=12`/`CONTEXT_NATIVE_CACHE`).
2. **lterm status 백엔드 라우팅 인프라 배선** — §0C 이월의 "라우팅 실제 배선" **1단계 완료(behavior-preserving)**. PoC `select_status_backend`(이전 `#[allow(dead_code)]`)를 attach 진입부에 실배선:
   - `status_enabled = select_status_backend(policy, &gather()) != Disabled && requests_row()` — 기존 `status_bar_supported(requests_row())`와 **정확히 동치**(backend≠Disabled ⟺ !forced_off && terminal_capable). 미사용된 `status_bar_supported` 제거.
   - `gather_status_env_snapshot` 신설(실 env→StatusEnvSnapshot).
   - **지뢰 처리(이월 항목)**: `tmux_compat::inside_cmux` `pub(crate)` 승격, `detect_real_tmux`+순수 `is_self_provided_tmux`로 lterm self-TMUX(`server::fake_tmux_value`=`{lterm_socket},{pid},0` + `LTERM_SOCKET` export) 식별 → **real_tmux 오분류 방지**. `detect_is_iterm`. `#[allow(dead_code)]` 4개 제거.
   - → **lterm PR #122 머지**(main `fbeade0`). code-reviewer APPROVE(동작 동치 검증). 미구현 백엔드(NativeChrome/DelegatedSurface/TitleCueDelegation)는 `status_enabled`(bool)로 환원돼 기존 DECSTBM 경로 그대로(동작 불변) → **라이브 검증 불필요**.
3. **understatus `workspace.repo` 타입 드리프트 수정 (진짜 ctx 소멸 원인)** — 사용자가 "여전히 ctx 안 보임" 보고 → **statusLine stdin 라이브 캡처**로 진단: Claude Code가 `workspace.repo`를 문자열→`{"host","owner","name"}` **객체**로 바꿨는데 understatus `RawWorkspace.repo: Option<String>`이 거부 → `RawClaudeInput` **전체 파싱 실패** → model/ctx/cost/git이 통째 사라지고 시스템 지표만 남음. (`used_percentage` 60%는 정상 전달됐고 파싱만 실패 — §0-1 ctx 수정과 무관한 별개 회귀.) 실제 payload에서 repo만 문자열로 바꾸면 ctx 즉시 복구로 확정.
   - **수정**: `deserialize_lenient_string`(Value로 받아 문자열만 추출, 객체/숫자/배열/bool/null→None) 추가. `RawWorkspace`(4필드)·`RawModel`(2필드)·`RawClaudeInput` 최상위(session_id/cwd) String 필드에 적용 → 표시·캐시키 String 필드 **일반화 방어**(향후 다른 필드 객체화도 안전). git_worktree 우선 폴백 보존. **(별개)** hold TTL 30s→**600s** 상향(긴 used_percentage 누락 대비).
   - → **understatus PR #10 머지**(main `930d6be`). code-reviewer APPROVE. **293 테스트**(repo 객체 드리프트 보존 등 +5). 라이브 화면 ctx 복귀 사용자 확인.
   - **진단 교훈**: 증상을 추측(TTL)하지 말고 **statusLine stdin을 캡처**해 측정하라. 캡처 래퍼는 `tee`(부분쓰기 race) 대신 stdin 전체를 변수로 받아 원자적 append. 두 Claude 세션이 동시 활성이면 전역 캡처 파일에 섞이니 `session_id`/`cwd`로 구분.

### ⏭ 다음 세션 이월
1. **lterm status 실렌더 트랙**(가장 큰 가치, 미구현). 라우팅은 라이브지만 비-DECSTBM 백엔드는 아직 DECSTBM로 환원됨. 트랙별:
   - **DelegatedSurface(Cmux)** — ⚠️ **선결 조사 필요**: cmux split은 surface **ref 문자열만** 주고(`open_cmux_split`/`send_cmux_attach`는 attach 명령 **1회** 주입), lterm은 그 surface에 status 바이트를 **주기적으로 쓸 write 핸들이 없음**. `cmux send --surface <ref> <raw SGR>`가 지원되는지 **cmux CLI 계약을 document-specialist로 조사**해야 실현 가능 판정(lterm 레포엔 cmux 구현 없음).
   - **NativeChrome(iTerm OSC1337)** — from-scratch(코드 전무). `.poc/poc2-iterm-status.sh`가 검증법 제시(SetUserVar base64 plain text, truecolor/멀티라인 불가). base64 `protocol.rs:309`(pub 승격 필요), iTerm 식별 `detect_is_iterm` 이미 있음.
   - 배선점: `attach_pty_rows`(client.rs ~3595)가 "본문 1행 양보 여부" 단일 결정점 — 비-DECSTBM 백엔드는 full `rows` 전달해야 함. 콘텐츠 계약(`LTERM_STATUS_COMMAND`→`command_line`)은 backend-무관 재사용 가능(소비점은 `build_draw_body` 1곳).
   - 실렌더는 동작을 바꾸므로 **라이브 PTY attach 육안 검증 필수**(자동 테스트로 색·입력칸 회귀 못 잡음 — HANDOFF 반복 교훈).
2. **understatus 잔여 LOW**(알려진 한계): display=None 내는 극단 프레임(양수 native 부재 + 600s TTL 초과 + 토큰 fallback 부재 = 사실상 cold-start)엔 omc strip과 겹쳐 ctx 잠깐 빔. 빈도 낮고 cold-start는 빈 게 맞아 미수정.
3. **lterm 릴리스**(선택): lterm 라우팅 인프라 배선(#122)은 main에 있으나 v1.0.22 이후 **미릴리스**. 동작 불변(behavior-preserving)이라 급하지 않음. 실렌더 트랙 완료 시 함께 릴리스 권장.

### 검증 수치(이번 세션)
- understatus main(v0.4.0): clippy 클린, **293 테스트**, release `--locked` 빌드 클린, CI 그린.
- lterm main: **1.96** clippy `-D warnings` 클린, unit **377**, release 클린, CI 7체크 SUCCESS.
- ⚠️ **lterm CI는 stable 1.96**(2026-05-28~). 로컬 rustup stable이 1.94면 `manual_option_zip` 등 신규 lint를 못 잡음 → `rustup toolchain install 1.96.0` 후 `cargo +1.96.0 clippy`로 CI 일치 검증(이번 세션 그 lint로 CI 1차 실패→로컬 1.96으로 재현·수정).
- lterm cli_smoke `notify_*cmux*`는 병렬 `CMUX_*` env 경합 flaky → `--test-threads=1` 또는 단독 실행(본 변경 무관).

### PR 상태 (전부 머지, 열린 PR 0)
- understatus: **#9**(ctx fix) · **#10**(repo drift fix) · **#11**(v0.4.0 범프) · **#12**(homebrew 사본 동기화) 전부 merged.
- lterm: **#122**(라우팅 인프라 배선) merged.

### 릴리스 (understatus v0.4.0 — 4채널 라이브 ✅)
v0.3.0 이후 누적분(lterm statusline 통합·codex 심층판독·strip_chain_ctx·ctx fallback/hold·repo drift fix)을 minor bump로 배포 완료:
- **crates.io**: v0.4.0 published(sparse index 확정). **npm**: `understatus@0.4.0`. **GitHub Release**: v0.4.0(arm64+x64 tar.gz+sha256). **Homebrew**: tap `ictechgy/homebrew-understatus` Formula v0.4.0(소스 빌드, 소스 아카이브 sha256 `483672d2…`) + repo 사본 동기화.
- 절차 메모(§C 보강): 태그 push→`release.yml`(macos-14 arm64+x64)→`cargo publish --allow-dirty`(IRREVERSIBLE, credentials.toml 보유)→Homebrew tap 직접 push(별도 PR 불요, formula는 **소스 아카이브** sha256 사용)→npm은 **사용자가 passkey**로 `npm publish ./npm --access public`(에이전트 불가). npm postinstall E2E로 v0.4.0 release 바이너리 수신·ctx 표시 확인.

---

## §0C. 직전 세션 (2026-06-07) — 완료/배경

> 직전 세션의 활성 작업은 §A(Phase 1)가 아니라 아래였다. §A~E는 배경/참고로 보존. 상세 상태는 자동메모리 `lterm-status-default-on`에 누적.

### ✅ 완료 (전부 양쪽 main 머지됨)
1. **Codex 세션 심층판독 (Phase 2-1)** — understatus가 `~/.codex/sessions/**/rollout-*.jsonl` 파싱해 model/ctx%/rate-limit/plan/effort 표시(`--source lterm` + agent=codex). `src/codex.rs`, `[codex]` config(enabled/freshness_minutes/scan_days), `src/claude.rs` 세션/페인 라벨. → **understatus PR #6 머지** (§B-1 완료).
2. **omc ctx 튐 진단·수정** — statusLine(understatus)은 기존 statusLine(omc HUD)을 `[chain]`으로 자식 실행해 합성하는데, 그 **체인된 omc HUD**가 Claude payload `used_percentage` 누락 시 토큰비율로 ctx를 발명해 86↔98로 튐(understatus 자체는 순수통과=무죄, 통제 재현으로 증명). understatus가 체인 출력에서 omc의 ctx 표시만 외과 제거(`[chain] strip_chain_ctx`, 기본 on). `src/chain.rs::strip_chained_context`(ANSI-aware·UTF-8 안전·bar/색/경고줄 처리)+13테스트. → **understatus PR #8 머지**(원래 #7; 스택 머지 중 base 삭제로 auto-close되어 #8 재생성). code-review APPROVE.
3. **lterm status-row 안정화** — content-only 백스톱(`force_content_redraw`): 주기 백스톱이 reserve(DECSTBM)를 재방출→codex scroll-region 침범→입력칸 증식하던 회귀 제거. + self-heal/dedup/cursor-hide. → **lterm PR #121 머지**. **라이브 시각검증 PASS**(다른 cmux 창 갔다 와도 입력칸 깔끔 — 사용자 확인).
4. **cross-env status 백엔드 라우팅 PoC** (lterm #121, **미배선**) — `select_status_backend(policy, &StatusEnvSnapshot) -> StatusBackend`(Disabled/DecstbmOverlay/NativeChrome/DelegatedSurface(Cmux|Tmux)/TitleCueDelegation) 순수 결정함수 + 8 라우팅 테스트. `#[allow(dead_code)]`라 런타임 영향 0.
5. lterm 바이너리: `~/.local/bin/lterm`은 `target/release/lterm` **심볼릭 링크** → 새 빌드가 곧 설치본(새 `lterm a`부터 #121). 데몬 핫스왑 안 됨, 새 attach 필요. status는 **client(attach) 측 렌더**라 데몬 재시작 불필요.

**연구 결론(핵심)**: 일반 터미널 + 메인버퍼 에이전트(codex)에서 **분리형 status 한 줄의 무손상 공존은 원리적으로 불가능**(DECSTBM 단일 전역 자원, host가 에이전트 scroll-region 질의 불가, alt-screen 게이트는 메인버퍼라 무력). best-effort=~50ms 수렴. 안전은 host=터미널(tmux/cmux) 또는 셀 그리드 밖 네이티브(iTerm OSC1337/탭)일 때만 성립.

### ⏭ 다음 세션 이월 — 라우팅 **실제 배선** (PoC만 머지됨)
`select_status_backend`는 결정만, 렌더 배선 미구현. 단계:
- `client.rs` `status_enabled`(~3089) 직후 `select_status_backend` 호출로 분기. PTY rows-1 clamp/reserve는 `DecstbmOverlay`일 때만.
- `StatusBackend` trait(reserve/draw/teardown 3메서드) — 공통 콘텐츠 계약은 기존 `LTERM_STATUS_COMMAND`+stdin JSON(`build_status_payload` v1)+stdout SGR passthrough 재사용(테마/펄스/세션라벨 N분기 방지).
- cmux 배선: attach 경로에서 `open_cmux_split`/`send_cmux_attach`(현재 tmux-compat split 핸들러에서만 호출) 신규 호출.
- **배선 지뢰(반드시 처리)**: ① `real_tmux`는 lterm이 자식에 TMUX를 **스스로 export**하므로 순진한 `$TMUX` 판정 시 오분류 → lterm-injected TMUX 식별해 `real_tmux=false`. ② `tmux_compat::inside_cmux`는 **private** → `pub(crate)` 승격. ③ NativeChrome OSC1337 값은 **base64 인코딩 필수**(`.poc/poc2`처럼) — OSC 인젝션 차단. ④ 멀티라인은 DelegatedSurface(cmux/tmux)에서만, DECSTBM/NativeChrome은 단일라인 격하.
- 배선 후 `.poc/poc2-iterm-status.sh`(iTerm), `.poc/poc3-convergence.md`(수렴+입력칸) 라이브 검증.

### 검증 수치(이번 세션 최종)
- understatus main: 빌드 클린 + **258 테스트**(250+8) 통과.
- lterm main: **581 테스트**(373 unit + 201 cli_smoke + 7 lifecycle) 통과, release 무경고.
- lterm #121 **quad-review-loop**: 4렌즈(정확성/보안/적대적/테스트) + round-2 델타 재검토, **CRITICAL/HIGH/확정블로커 0**, critic ACCEPT.

### PR 상태 (전부 머지/정리됨, 열린 PR 0)
- understatus: **#6**(codex) merged · **#8**(strip, =구 #7) merged.
- lterm: **#121**(status-row 안정화 + 라우팅 PoC) merged · **#120**(self-heal, #121이 supersede) closed.

---

## §A. 배경(Phase 1, 완료) — lterm × understatus statusline 통합

### 목표
Codex CLI는 Claude Code식 **command-backed statusline**(스크립트가 stdin JSON 받고 포맷 텍스트 반환 → 하단 렌더)을 미지원(공식 FR `openai/codex#17827`). 그래서 사용자의 터미널 세션 데몬 **lterm**(tmux 유사, 화면을 소유, `lterm codex` 등 에이전트 래핑 내장)의 하단 status row를 **command-backed로 확장**해, lterm 안에서 도는 모든 에이전트(Codex·Gemini·Claude…)가 에이전트 자체 지원과 무관하게 understatus statusline을 얻게 한다.

**사용법 (양쪽 main에 머지 완료):**
```bash
LTERM_STATUS_COMMAND="understatus render --source lterm --oneline" lterm codex
```

### 현재 상태 = Phase 1 완료, 양쪽 레포 main 머지됨 ✅
- **understatus** (이 레포): **PR #5 머지** → main. `render --source lterm` + `--oneline` 추가.
  - `src/claude.rs::parse_lterm_input`(lenient, git 비활성, cwd 표시용, session_key 합성), `src/main.rs` `render --source <claude|lterm>`/`--oneline` 파서 + `run_render_pipeline(source, oneline)`, `tests/oneline.rs`.
  - 설계/합의 문서: `docs/superpowers/specs/2026-06-05-lterm-statusline-integration-design.md` (ralplan 합의 APPROVE본 — **Phase 2 백로그는 이 문서 §15**).
- **lterm** (`/Users/jinhongan/Desktop/light_terminal`, 제품=lterm): **PR #119 머지** → main (6커밋 `980c4b5..6a66a33`).
  - `src/sanitize.rs`: `sanitize_status_command_line`(신뢰 불가 stdout → **SGR-only 화이트리스트**, C1 CSI 차단, OSC/DCS/미완결 ESC 폐기, 단일행 강제, param `[0-9;:]`만+길이64/개수16 상한) + `truncate_status_line_ansi`(SGR 원자 보존+grapheme/CJK 폭 절단+끝 `\x1b[0m`).
  - `src/client.rs`: `StatusCommandConfig`(env), `agent_name_from_command`, `build_status_payload`(serde JSON, 필드 길이 cap), `run_status_command`(셸 미경유 argv spawn, stdin→EOF, **reader 스레드+deadline로 status 스레드 무블로킹**, kill/wait 좀비 회수, 64KB 상한, process_group(0)), `spawn_status_command_thread`/`apply_pending_status_command`(metadata 동형), `StatusBar.command_line`+`draw_at_size` 통합(ANSI=1이면 테마 bg off+understatus 색), `attach` 배선, interruptible sleep, alt-screen pause.

### env/flag (lterm)
| 키 | 기본 | 의미 |
|---|---|---|
| `LTERM_STATUS_COMMAND` | (없음) | 설정 시 status row를 이 명령 출력으로. 미설정 시 기존 동작(세션+페인) **바이트 동일**. |
| `LTERM_STATUS_INTERVAL` | `2` | 초, `1..=3600` 클램프 |
| `LTERM_STATUS_ANSI` | `1` | 색 통과(SGR-only). `0`=strip(plain, 테마 bg 유지). **사용자가 =1 확정**(understatus 색 위주). |
| `LTERM_STATUS_DEBUG` | `0` | `1`이면 명령 실패/타임아웃 stderr 1줄 |

### stdin JSON 계약 (lterm → understatus)
```json
{"source":"lterm","version":1,"session":"codex","pane":"%3",
 "session_key":"codex/%3","agent":"codex","cwd":"...","cols":120,"rows":40}
```
- understatus는 lenient: 미상 필드 무시, 빈 `{}` 무패닉. `version`은 읽되 무시(forward-compat). ignored 필드(version/cols/rows/source)는 `serde_json::Value`로 관대 — 타입 드리프트가 전체 파싱을 안 깸.
- **Phase 1에서 git branch 비활성**: understatus git 도출은 `workspace.git_worktree|repo`(워크트리 루트)를 요구하는데 lterm `SessionInfo.cwd`는 세션 시작 dir라 보장 안 됨 → cwd→branch 안 함(`$PWD` 폴백 코드 없음). git은 Phase 2(walk-up).

### 검증 (이번 세션, 양쪽 독립 확인)
- understatus: clippy `-D warnings` 클린, fmt 클린, 테스트 **205**, E2E OK.
- lterm: clippy 클린, fmt 클린, 단위 **352**, release 빌드, **라이브 PTY E2E PASS**(3회 — 실제 attach 화면 status row에 understatus truecolor 출력 `· mem 48% · disk 77% …`).
- 양쪽 **quad-review-loop SUCCESS**(4모델 교차검증). lterm R1에서 **실제 subprocess HIGH blocker**(stdin write/stdout read_to_end 무한 블로킹)를 적발·수정한 게 핵심 성과.

---

## §B. Phase 2 (다음 세션 — 선택, 우선순위순)

spec `docs/superpowers/specs/2026-06-05-lterm-statusline-integration-design.md` §15 참조.

1. ~~**Codex 세션 심층판독**~~ ✅ **완료**(§0-1, understatus #6 머지). `src/codex.rs`로 `~/.codex/sessions/**/rollout-*.jsonl` 파싱→model/ctx%/rate-limit/plan/effort.
2. **git branch**: `--source lterm`에서 cwd→`.git` walk-up(워크트리 루트 도출) 또는 payload에 `git_worktree` 추가.
3. **`mode=pane`** (split, full truecolor 다행): **연구 완료**(§0 연구결론, 메모리 §A). cmux=ghostty 기반 GUI 멀티플렉서, 별도 surface=ghostty PTY라 scroll-region 충돌 **구조적 부재**, lterm 이미 cmux 통합(`open_cmux_split`/`send_cmux_attach`) 보유 → 라우팅 배선(§0 이월)의 `DelegatedSurface(Cmux)` 트랙으로 구현. "OMX HUD-watch 재사용"은 실체 없음(omx HUD엔 ctx 요소 자체 없음).
4. **TOML `[status]` config** + `lterm attach --status-command` CLI 플래그(현재 env-only). lterm에 config 로더·`toml` 의존 없음 → 신설 필요.
5. **다중 에이전트 세그먼트**(Gemini/OpenCode 등 전용 표시).
6. **lterm 잔여 LOW**(비차단, quad-review 문서화됨):
   - `build_status_payload`가 daemon의 `info.agent_name`(protocol.rs/server.rs) 대신 `info.command` 재파싱 → daemon값 우선 사용.
   - reader 스레드 detach가 자손-stdout-점유 시 leak 가능 → 완전 해결은 process **group-kill**(`kill(-pgid)`, libc/nix 의존 필요) = Phase 2.
   - `split_sgr_and_text`는 살균 출력 전제(docstring 명시) — pub/재사용 시 주의.
   - status row 테마 bg 옵션화(ANSI=1에서도 bg 유지 선택), spawn 실패 백오프.

---

## §C. 배경 — understatus v0.3.0 (이미 출시됨)

> 제품은 **v0.3.0가 4채널 모두 라이브**. 위 statusline 작업은 그 위에 얹은 미릴리스 기능(아직 새 버전 안 냄 — 릴리스하려면 §C 릴리스 절차).

- **GitHub(공개):** https://github.com/ictechgy/understatus (default `main`).
- **lterm GitHub:** https://github.com/ictechgy/light_terminal (default `main`). Homebrew: `brew install ictechgy/tap/lterm`.
- **understatus 채널(전부 v0.3.0 라이브):** crates.io(`cargo install understatus`), Homebrew(`ictechgy/understatus/understatus`), npm(`understatus`), GitHub Release.
- **언어/플랫폼:** Rust 2021, **macOS only**(arm64+Intel). understatus build.rs는 IOKit+CoreFoundation 링크.

### ⚠️ Auth (지난 세션에 물림)
- **`gh` 토큰 만료 가능**. `gh auth status`가 invalid여도 `git push`(osxkeychain)·일부 `gh` API는 동작할 수 있음. `gh` 실패 시 `gh auth refresh -h github.com`(브라우저 — 에이전트 불가, 사용자에게). **이번 세션엔 gh 정상**이었음(PR #5/#119 생성·머지 성공).
- **npm publish/deprecate는 브라우저 passkey(EOTP) 필요** — 에이전트 일반적으로 불가.

### understatus 릴리스 절차 (v0.3.x+, 새 버전 낼 때)
1. **3종 버전 범프**: `Cargo.toml`, `npm/package.json`, `npm/install.js`(`const VERSION`) + `cargo build`로 `Cargo.lock` 갱신. 브랜치→PR→**rebase-merge**.
2. `git tag -a vX.Y.Z && git push origin vX.Y.Z` → `release.yml`(macos-14, arm64+x64) 그린 **대기 후** `cargo publish --allow-dirty`(IRREVERSIBLE).
3. Homebrew tap `Formula/understatus.rb` 갱신 — **⚠️ v0.6.0부터 prebuilt 바이너리 방식**(소스빌드 아님): `version "X.Y.Z"` + `on_arm`/`on_intel` 각 `url`(GitHub Release **바이너리** tarball)·`sha256`을 갱신. sha256은 릴리스의 `.sha256` 에셋에서 받음(`curl -sL <release>/understatus-X.Y.Z-<triple>.tar.gz.sha256 | awk '{print $1}'`, **소스 아카이브 아님**). `depends_on "rust"`/`cargo install` 없음 → 설치에 CLT 불필요. `brew style` 클린 + `brew install`로 "built in N seconds"(컴파일0) 실설치 검증. tap 직접 push, repo `homebrew/understatus.rb` 사본 동기화(별도 PR).
4. npm: 로컬 `npm install ./npm --prefix /tmp/test --foreground-scripts` E2E(install.js가 vX.Y.Z 바이너리 SHA-256 수신 확인) 후 **사용자**가 `npm publish ./npm --access public`(EOTP passkey).

---

## §D. 이번 세션에서 배운 것 (반복 회피)

- **워크플로**: brainstorming → ralplan(합의) → spec → 청크 단위 구현(executor) → quad-review-loop → 머지. 효과적이었음. ralplan/quad-review가 **코드 사실 불일치·실제 보안 blocker를 잡음**(예: understatus가 cwd로 git 도출 안 함; lterm subprocess 타임아웃이 전체를 못 막음).
- **agy(Antigravity)**: 리뷰형 프롬프트 **~8KB 초과 시 hang** → 큰 diff에선 매번 SKIP(정상). 가용 3트랙(Claude+Codex+Forge)으로 합의.
- **Forge(forgecode)**: 큰 프롬프트에서 **구조화 출력 없이 reasoning 스트림만** 내는 경우 많음 → verdict/JSONL 없으면 **폐기**(합의에서 제외). flaky.
- **executor 장시간 태스크**: 매우 긴 단일 태스크에서 **API 소켓 에러로 중단**된 사례 있음 → 큰 작업은 **청크로 분할**(lterm은 3청크: 게이트→플러밍→draw통합)하면 안정적. 중단 시 부분 변경 확인 후 직접 마무리 가능.
- **lterm status bar는 attach 클라이언트가 그리는 chrome** → `lterm logs`/`capture`(scrollback)엔 안 나옴. 관측하려면 **실제 PTY attach** 필요(python `pty.fork` 하니스로 캡처 → 출력에 `mem`/`disk`+`\x1b[38;2;` 있으면 렌더 성공).
- **lterm AGENTS.md/HANDOFF.md는 gitignored**(로컬). 검증 스위트: `cargo fmt -- --check`/`cargo clippy --all-targets -- -D warnings`/`cargo test`/`cargo build --release --locked`/`cargo audit`. **의존성 추가는 정당화 필요**(group-kill용 libc 등은 신중히).
- **quad-review-loop blocker 기준** = severity HIGH+ AND consensus(≥2 트랙). MEDIUM/LOW는 루프를 안 멈추지만, 사용자는 실제 MEDIUM도 고치는 걸 선호(이번에 다 반영).

---

## §E. 빠른 상태 확인
```bash
# understatus (이 레포)
cd /Users/jinhongan/Desktop/status_ticon/statusticon
export PATH="$HOME/.cargo/bin:$PATH"
git log --oneline -8        # main `558aafb`: gitfile FN 가드(#24) + M-2(#23) + git pill 견고화(#22) + 아이콘 SF Symbol(#21) ...
cargo test                  # 328(lib)+14(oneline)=342 통과 (rustup: ~/.cargo/bin/cargo)
grep '^version' Cargo.toml  # 0.6.0 (4채널 라이브 — 이번 세션 내부 hardening이라 범프 불요)
echo '{"source":"lterm","session":"codex","pane":"%3","cwd":"'$PWD'"}' \
  | COLORTERM=truecolor ./target/release/understatus render --source lterm --oneline | cat -v

# lterm
cd /Users/jinhongan/Desktop/light_terminal
export PATH="$HOME/.cargo/bin:$PATH"
git log --oneline -5        # main: Merge #123(af59ab9, cmux pills 실렌더) + 라우팅 배선 #122
cargo test --bin lterm      # 417 통과. cli_smoke는 cmux env 경합 flaky → --test-threads=1
# CI는 stable 1.96: 로컬은 `rustup toolchain install 1.96.0` 후 `cargo +1.96.0 clippy --all-targets -- -D warnings`로 일치 검증
# 라이브 E2E: LTERM_STATUS_COMMAND="<understatus 절대경로> render --source lterm --oneline" lterm codex
# 입력칸 fix 시각검증: ~/.local/bin/lterm(=target/release 심볼릭) 새 attach로 codex 띄우고 cmux 창 전환→복귀
```