oh-my-customcode 1.1.66 → 1.1.68

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/cli/index.js CHANGED
@@ -217,7 +217,7 @@ var init_package = __esm(() => {
217
217
  workspaces: [
218
218
  "packages/*"
219
219
  ],
220
- version: "1.1.66",
220
+ version: "1.1.68",
221
221
  description: "Batteries-included agent harness for Claude Code",
222
222
  type: "module",
223
223
  bin: {
package/dist/index.js CHANGED
@@ -2326,7 +2326,7 @@ var package_default = {
2326
2326
  workspaces: [
2327
2327
  "packages/*"
2328
2328
  ],
2329
- version: "1.1.66",
2329
+ version: "1.1.68",
2330
2330
  description: "Batteries-included agent harness for Claude Code",
2331
2331
  type: "module",
2332
2332
  bin: {
package/package.json CHANGED
@@ -3,7 +3,7 @@
3
3
  "workspaces": [
4
4
  "packages/*"
5
5
  ],
6
- "version": "1.1.66",
6
+ "version": "1.1.68",
7
7
  "description": "Batteries-included agent harness for Claude Code",
8
8
  "type": "module",
9
9
  "bin": {
@@ -298,6 +298,10 @@ split("\n")
298
298
  # 미announce Read — 은 새로 발화한다(의도된 동작, v1.1.62 적대적 리뷰 재현 C1/C2).
299
299
  | ($an_tool + (if $an_spawn > $an_tool_agent then $an_spawn - $an_tool_agent else 0 end)) as $announce
300
300
  | ([ $blocks[] | select((.type? == "tool_use") and ((.name? // "") != "Skill")) ] | length) as $ntools
301
+ # 미접두 도구 이름 (#1687): $ntools와 동일한 필터(non-Skill tool_use)로 순서를 보존한 이름
302
+ # 목록을 뽑는다. $r008(누락 건수)이 어떤 도구인지 shell에서 드러내기 위한 부가 필드 —
303
+ # 판정식($r008 산출) 자체는 건드리지 않는다.
304
+ | ([ $blocks[] | select((.type? == "tool_use") and ((.name? // "") != "Skill")) | (.name? // "") ]) as $tool_names_list
301
305
  # 전체 tool_use(Skill 포함)가 0건인 턴은 forward 판정을 무조건 0으로 고정한다(#1625
302
306
  # 찐빠 #3, 이슈 제안 그대로). $ntools(Skill 제외) 기반 산식은 정상 입력에서는 이미
303
307
  # 0을 내지만, 명시 가드로 불변식을 코드에 못박아 향후 산식 변경이 이 보장을 조용히
@@ -322,7 +326,7 @@ split("\n")
322
326
  | ([ $lines[] | select(test("^\\[[^\\]]+\\]\\[[^\\]]+\\] ?(→|->|—>) ?Tool:")) ] | length) as $an_anchored
323
327
  # $nall_tools는 위 forward r008 가드에서 이미 바인딩됨 — 재바인딩하지 않고 재사용한다.
324
328
  | (if $nall_tools == 0 and $an_anchored > 0 then $an_anchored else 0 end) as $r008rev
325
- | [$tuuid, ($r007 | tostring), ($r008 | tostring), ($r008rev | tostring)] | @tsv
329
+ | [$tuuid, ($r007 | tostring), ($r008 | tostring), ($r008rev | tostring), ($tool_names_list | join(","))] | @tsv
326
330
  )
327
331
  end
328
332
  end
@@ -346,6 +350,8 @@ turn_uuid=$(printf '%s' "$result" | cut -f1)
346
350
  r007_violations=$(printf '%s' "$result" | cut -f2)
347
351
  r008_violations=$(printf '%s' "$result" | cut -f3)
348
352
  r008_reverse=$(printf '%s' "$result" | cut -f4)
353
+ # 미접두 도구 이름 목록 (#1687) — $ntools와 동일 필터의 순서 보존 목록, "," join.
354
+ tool_names=$(printf '%s' "$result" | cut -f5)
349
355
 
350
356
  : "${r007_violations:=0}"
351
357
  : "${r008_violations:=0}"
@@ -397,6 +403,26 @@ if [ "$r008_violations" -gt 0 ]; then
397
403
  violation_desc="R008 도구 식별 접두사 누락 ${r008_violations}건"
398
404
  instruction="모든 도구 호출에 [agent][model] → Tool: 접두사를 포함하십시오."
399
405
  fi
406
+ # 미접두 도구 이름 귀속 (#1687): announce는 턴 단위로 매칭되므로, $tool_names(순서 보존,
407
+ # non-Skill tool_use)의 마지막 r008_violations개를 부족분으로 귀속한다. 카운트 문구
408
+ # "R008 도구 식별 접두사 누락 N건"은 위에서 이미 확정되어 바이트 동일 유지 — 이 접미사는
409
+ # 항상 그 뒤에 이어붙인다(scripts/count-r007-r008.sh의 grep -oE 앵커와 무관).
410
+ if [ -n "$tool_names" ]; then
411
+ r008_missing_tools=$(printf '%s' "$tool_names" | awk -F',' -v n="$r008_violations" '{
412
+ total = NF
413
+ start = total - n + 1
414
+ if (start < 1) start = 1
415
+ out = ""
416
+ for (i = start; i <= total; i++) {
417
+ if (out != "") out = out ", "
418
+ out = out $i
419
+ }
420
+ print out
421
+ }')
422
+ if [ -n "$r008_missing_tools" ]; then
423
+ violation_desc="${violation_desc} (미접두 도구: ${r008_missing_tools})"
424
+ fi
425
+ fi
400
426
  fi
401
427
 
402
428
  if [ -n "$violation_desc" ]; then
@@ -597,13 +597,34 @@ raw_command=$(printf '%s' "$input" | jq -r '.tool_input.command // ""')
597
597
  # Distinguish "the same file edited 3 times with DIFFERENT content" (a normal
598
598
  # incremental-edit workflow — the #1641 false positive) from "the same edit
599
599
  # repeated 3 times" (a genuine stuck loop). Only the latter should hard-block.
600
- # Alphanumerics-only + length cap: deterministic, platform-independent (no
601
- # md5sum, absent on macOS) and safe to embed in a grep pattern.
600
+ # #1649: the original alphanumerics-only + 120-char-cut key had two defects —
601
+ # (M-1) edits differing only in punctuation/whitespace (e.g. re-aligning a
602
+ # markdown table) collapsed to the SAME key and were falsely blocked as
603
+ # "identical", and (M-2) Write calls sharing a long identical prefix (e.g.
604
+ # frontmatter) collided after the 120-char cut even when the body differed.
605
+ # New spec: collapse whitespace runs to one space (still deterministic,
606
+ # platform-independent, no md5sum) but PRESERVE punctuation, then key on
607
+ # "<len>#<full>" when the normalized string is <=120 chars (short strings fit
608
+ # whole, so no sum is needed), else "<len>#<codepoint sum>#<first 80 chars>
609
+ # #<last 40 chars>" — length + codepoint sum + head/tail. Adversarial review
610
+ # found the length+head+tail-only key (no sum) still collides when a
611
+ # same-length middle-only substitution falls entirely outside both the head
612
+ # and tail windows (e.g. this repo's own count/version-bump Writes: 80 "A"s +
613
+ # "version-115-count" + 40 "Z"s vs "...-116-..." vs "...-117-..." — all 137
614
+ # chars, identical head/tail). The codepoint sum changes whenever the changed
615
+ # substring's characters change, so a substitution is now caught by the sum;
616
+ # a same-sum transposition of the middle segment can still collide — an
617
+ # accepted residual risk, not fully eliminated.
602
618
  edit_hash=""
603
619
  if [ "$tool_name" = "Edit" ] || [ "$tool_name" = "Write" ]; then
604
620
  edit_hash=$(printf '%s' "$input" \
605
621
  | jq -r '(.tool_input.old_string // .tool_input.content // .tool_input.new_string // "")
606
- | gsub("[^A-Za-z0-9]"; "") | .[0:120]')
622
+ | gsub("[[:space:]]+"; " ") | ltrimstr(" ") | rtrimstr(" ")
623
+ | (length as $l
624
+ | if $l <= 120 then "\($l)#\(.)"
625
+ else ((explode | add // 0) as $sum
626
+ | "\($l)#\($sum)#\(.[0:80])#\(.[-40:])")
627
+ end)')
607
628
  fi
608
629
 
609
630
  # History entries are written by jq, so their "path" values are JSON-ENCODED.
@@ -615,6 +636,15 @@ fi
615
636
  target_key_json=$(jq -n --arg v "$target_key" '$v')
616
637
  path_match="\"path\":${target_key_json}"
617
638
 
639
+ # #1649 follow-up: edit_hash now preserves punctuation (see the edit_hash
640
+ # comment above), so it can contain quotes/backslashes just like a Bash
641
+ # command can. It is written to history the same JSON-encoded way "path" is
642
+ # (--arg ehash "$edit_hash" -> jq serializes it), so Check 1 / Check 3 below
643
+ # must match it with the SAME JSON-encoded literal, not the raw string — same
644
+ # fix as path_match above, applied to edit_hash.
645
+ edit_hash_json=$(jq -n --arg v "$edit_hash" '$v')
646
+ edit_hash_match="\"edit_hash\":${edit_hash_json}"
647
+
618
648
  is_readonly="false"
619
649
  if [ "$tool_name" = "Bash" ]; then
620
650
  is_readonly=$(is_readonly_bash_command "$raw_command")
@@ -761,7 +791,7 @@ if [ -f "$HISTORY_FILE" ]; then
761
791
  if [ "$is_readonly" != "true" ] && [ -n "$file_path" ]; then
762
792
  consecutive_file=$(printf '%s\n' "$last_n" \
763
793
  | grep -F -e "$path_match" \
764
- | grep -cF -e "\"edit_hash\":\"${edit_hash}\"" 2>/dev/null || true)
794
+ | grep -cF -e "$edit_hash_match" 2>/dev/null || true)
765
795
  [ -n "$consecutive_file" ] || consecutive_file=0
766
796
  if [ "$consecutive_file" -ge "$HARD_BLOCK_THRESHOLD" ]; then
767
797
  hard_block=true
@@ -791,7 +821,7 @@ if [ -f "$HISTORY_FILE" ]; then
791
821
  consecutive_tool_target=$(printf '%s\n' "$last_n" \
792
822
  | grep -F -e "\"tool\":\"${tool_name}\"" \
793
823
  | grep -F -e "$path_match" \
794
- | grep -cF -e "\"edit_hash\":\"${edit_hash}\"" 2>/dev/null || true)
824
+ | grep -cF -e "$edit_hash_match" 2>/dev/null || true)
795
825
  [ -n "$consecutive_tool_target" ] || consecutive_tool_target=0
796
826
  if [ "$consecutive_tool_target" -ge "$HARD_BLOCK_THRESHOLD" ]; then
797
827
  hard_block=true
@@ -20,6 +20,8 @@
20
20
 
21
21
  > **zsh 내장 `echo`는 이스케이프를 확장한다 (#1625)**: zsh(이 저장소 Bash 도구 실행 셸)의 내장 `echo`는 `\n` 등 백슬래시 이스케이프를 기본 확장하므로, JSON 문자열을 파이프에 실을 때 `echo "$var"`를 쓰면 valid JSON을 스스로 깨뜨려 하류 파서 오진을 유발한다(v1.1.53 세션 훅 오진의 실제 원인). JSON/구조화 문자열 전달은 `printf '%s' "$var"`를 표준으로 한다.
22
22
 
23
+ > **zsh는 미인용 `$var`를 단어 분할하지 않는다 (#1683 #5)**: bash에서 관용적인 `for l in $list` / `set -- $line` 은 zsh(이 저장소 Bash 도구 실행 셸)에서 변수 전체를 **한 단어**로 취급하므로, `set -u`와 결합하면 `$2` 접근이 `parameter not set`으로 즉시 종료됩니다. 단어 분할이 필요하면 `${=var}`(zsh 전용) 또는 배열(`arr=(a b c); for x in "${arr[@]}"`)을 사용하고, 여러 필드가 든 문자열은 `read -r a b c <<< "$line"`으로 분해합니다. Origin: #1683 찐빠 #5 (v1.1.64 세션 — pre-triage 라벨 부트스트랩 스니펫이 1턴 실패 후 명시 인자로 재실행). Cross-ref: 위 zsh `echo` 노트, 파이프 `$?` 노트(#1540 zsh 변형) — 같은 "이 저장소의 셸은 zsh" 계열입니다.
24
+
23
25
  > **로컬 실행 옵션 제시 전 자원 가용성 선확인 (#1455 #2)**: 로컬 실행에 의존하는 검증 옵션(로컬 스모크 테스트, 로컬 스크립트 실행 등)을 사용자에게 제시하기 **전에**, 그 실행에 필요한 로컬 자원(env 키, CLI 도구, 인증 상태)의 가용성을 먼저 확인한다. **저장소 secret 존재 ≠ 로컬 셸 env 존재** — `gh secret list`로 저장소 secret을 확인해도 로컬 셸에 해당 env가 있으리라 단정하지 말 것. 자원 부재 시 옵션에 전제조건을 명시하거나 옵션에서 제외하여, 사용자가 실행 불가한 옵션을 선택했다가 되돌리는 왕복(AskUserQuestion 재질문)을 방지한다. Cross-ref: R020(사전 검증). Origin: #1455 #2 (Session 127 회고 찐빠 #2) — 사용자가 "로컬 스모크 테스트 먼저"를 선택했으나 로컬 셸에 ANTHROPIC_API_KEY 부재로 실행 불가 → "스킵, 바로 커밋" 재선택, AskUserQuestion 왕복 1회 발생.
24
26
 
25
27
  > **Shell output parsing — use Python, not read/grep (#1401 찐빠 #3)**: adb bounds rect, 좌표쌍, JSON 분할 등 구조화된 출력 파싱은 `read`+`grep -o` 파이프라인 대신 Python (`python3 -c "..."`) 을 사용한다. `read`+`grep -o` 조합은 공백 차이에 취약해 헛값을 산출한다. SSH 원격 `bash -c` 인자에 소괄호 포함 금지 — `ssh host "cmd; cmd2"` 형식 사용.
@@ -631,7 +631,8 @@ After restart/compaction: re-read CLAUDE.md, all delegation rules still apply. N
631
631
  | Kotlin/Spring | lang-kotlin-expert / be-springboot-expert |
632
632
  | Architecture docs | arch-documenter |
633
633
  | Test strategy | qa-planner |
634
- | CI/CD, GitHub config | mgr-gitnerd |
634
+ | CI/CD workflow files, GitHub config (branch protection, secrets) | mgr-gitnerd — `gh run rerun` is GitHub metadata, see next row |
635
+ | GitHub metadata only (issue create/comment/label/milestone, `gh run rerun`, read-only `gh` queries) | Orchestrator (direct) or mgr-gitnerd — see Rules bullet below |
635
636
  | Docker/Infra | infra-docker-expert |
636
637
  | Server deployment (docker, scp) | infra-docker-expert |
637
638
  | Server state changes (restart, env) | infra-docker-expert |
@@ -644,6 +645,7 @@ After restart/compaction: re-read CLAUDE.md, all delegation rules still apply. N
644
645
  - Use specialized agents, not general-purpose, when one exists
645
646
  - general-purpose only for truly generic tasks (file moves, simple scripts)
646
647
  - No exceptions for "small" or "quick" changes
648
+ - GitHub 메타데이터 작업(이슈 생성·코멘트·라벨·마일스톤, `gh run rerun`, 읽기 전용 `gh` 조회)은 프로젝트 파일 쓰기가 아니므로 오케스트레이터 직접 실행이 허용됩니다 — 위임도 허용되며, PR 생성·머지와 로컬 git 상태 변경은 계속 mgr-gitnerd 소유입니다 (Origin: #1683 찐빠 #6 — CI 재실행 4회·이슈 2건·코멘트 1건을 직접 실행했으나 소유 에이전트가 미명시였던 경계 모호).
647
649
 
648
650
  ### Protected Paths (mgr-creator Required)
649
651
 
@@ -85,11 +85,14 @@ Wiki verification is also enforced by CI (`.github/workflows/wiki-sync.yml`).
85
85
 
86
86
  **(b) 누락 방지**: `bun run build` 실행 후 `git status --short`에 **tracked 변경(`^ M`)이 남아 있으면 스테이징 누락**이다. 커밋 직전 tracked 변경이 0인지 확인한다.
87
87
 
88
+ **(c) untracked 신규 산출물 실측 (Origin: #1660 찐빠 #3)**: 커밋 위임서를 작성하기 직전 `git status --short | grep '^??'`로 untracked 목록을 실측하고, 위임서에 **포함할 신규 파일과 제외할 파일을 경로로 명시**합니다. `git add -u`나 "변경분을 커밋하라"만 지시하면 서브에이전트가 만든 신규 테스트·스크립트·픽스처가 커밋에서 빠지고, 반대로 광범위 `git add`는 이전부터 존재하던 무관한 untracked 파일(계획 문서·로컬 캐시 등)을 끌어들입니다. (a)·(b)가 tracked/gitignored 경로를 다룬다면 (c)는 그 사이의 **untracked 경로**를 다룹니다.
89
+
88
90
  | Anti-pattern | Required |
89
91
  |--------------|----------|
90
92
  | 빌드 후 광범위 `git add`로 커밋 → gitignored `dist/` force-add 위험 | 커밋 직전 `git diff --cached --name-only` 실측으로 빌드 산출물 부재 확인 |
91
93
  | .gitignore에 있으니 안전하다고 가정 | force-add 경로는 .gitignore를 우회하므로 실측 필요 |
92
94
  | `dist/` 미포함만 확인하고 커밋 → 빌드가 갱신한 tracked 산출물 누락 | `git status --short`로 tracked 변경 잔존 0 확인 |
95
+ | `git add -u`만 지시하거나 untracked 목록 미실측 → 신규 테스트 파일 누락 또는 무관 파일 혼입 | 위임 직전 `git status --short \| grep '^??'` 실측 → 포함/제외 경로를 위임서에 명시 |
93
96
 
94
97
  Origin: #1512 (v1.1.28 커밋 staging에 dist/ 2파일 포함, 커밋 전 실측으로 정정; v1.1.12 dist/ untrack 회귀 방지); #1531 (`.omcustom.lock.json`이 v1.1.29 이후 4개 릴리즈 연속 누락 — 혼입 방지 단방향 조항의 반대편 공백). Cross-ref: R020 (완료 검증 — "실행됨 ≠ 성공").
95
98
 
@@ -348,6 +348,8 @@ Temporal Decay(시간 경과 기반)와 Attention-Weight Tiering(접근 빈도
348
348
  - 세션 종료: 이번 세션 참조 여부 기반 tier 재평가 → archive 이동 실행
349
349
  - archive 이동 시: `sessions_archive_*.md`에 append, MEMORY.md에 인덱스 라인 유지
350
350
 
351
+ **위임서 표준 문안 (Origin: #1660 하네스 제안)**: sys-memory-keeper에 세션 메모리 갱신을 위임할 때 위임서에 "**압축·정리·티어 재평가 불요 — 지시한 항목만 기록**"을 명시합니다(정리가 필요하면 별도 위임으로 분리). 명시하지 않으면 에이전트가 자체적으로 MEMORY.md 압축을 목표에 추가해 턴 예산을 소진합니다 — v1.1.63 반복(#1660)에서 이 원인으로 15턴 절단이 2회 발생했습니다(R020 「maxTurns 절단 실증」의 메모리 위임 각도). 위 Tier 승강·archive 이동은 세션 종료 시 **별도 단일 목표 위임**으로 수행합니다.
352
+
351
353
  ## Mid-Session Immediate Save
352
354
 
353
355
  Save memory IMMEDIATELY upon surprising discovery — do not defer to session end.
@@ -10,12 +10,14 @@ effort: high
10
10
 
11
11
  # /omcustom:fsd — Full Self Driving
12
12
 
13
- Autonomous release loop. Equivalent to running:
13
+ Autonomous release loop. Can be expressed as running:
14
14
 
15
15
  ```
16
16
  /goal "모든 이슈가 처리될 때까지" /loop "/pipeline auto-dev -> /homework"
17
17
  ```
18
18
 
19
+ > The main conversation may also drive the same loop inline without invoking `goal`/`loop` — see 「인라인 실행 허용 — 계약과 실측의 정합 (#1683 #4)」 below.
20
+
19
21
  This is a **thin alias / orchestrator skill**. It does not implement loop, issue-polling, release, or verification logic — it delegates entirely to existing skills.
20
22
 
21
23
  ## Usage
@@ -119,6 +121,19 @@ printf '%s\n' "$(date -u +%Y-%m-%dT%H:%M:%SZ)" > "/tmp/.claude-fsd-$PPID"
119
121
  → NO → next iteration (re-write marker first)
120
122
  ```
121
123
 
124
+ ### 인라인 실행 허용 — 계약과 실측의 정합 (#1683 #4)
125
+
126
+ FSD의 루프 드라이버는 **메인 대화(오케스트레이터) 자신**입니다. `/goal`·`/loop`(ScheduleWakeup) 스킬 호출은 루프를 표현하는 한 방법일 뿐 필수 호출이 아니며, 오케스트레이터가 아래 최소 계약을 지키면 스킬 호출 없이 인라인으로 반복을 진행하는 것도 이 스킬의 정상 실행입니다. v1.1.64 반복이 인라인으로 실행된 것을 계약 이탈로 회고한 것(#1683 찐빠 #4)이 이 절의 기원이며, 같은 세션의 v1.1.65·v1.1.66 반복도 인라인으로 실행되었습니다(세션 실측, 이슈 범위 밖).
127
+
128
+ | 반복마다 지켜야 할 최소 계약 | 근거 |
129
+ |------------------------------|------|
130
+ | 반복 시작 시 무인 마커 갱신(`/tmp/.claude-fsd-$PPID`) | 위 「무인 모드 마커」 |
131
+ | `/pipeline auto-dev` 1회 → homework 아티팩트 1개 기록 → 열린 PR 처리 | 「Iteration Flow」 |
132
+ | 반복 끝에 수렴 판정(적격 이슈 0 AND 열린 PR 0)을 실측으로 수행 | R020 |
133
+ | 종료 경로와 무관하게 마커 제거(`command rm -f`) | 「무인 모드 마커」 |
134
+
135
+ `/goal`·`/loop`를 호출하는 경로는 여전히 유효하며, 세션이 무인(`claude -p`, 예약 실행)이라 자기 페이싱이 필요할 때 권장됩니다. 대화형 세션에서는 인라인 실행이 스킬 호출 오버헤드 없이 같은 계약을 만족합니다.
136
+
122
137
  ## Safety and Discipline
123
138
 
124
139
  Each iteration operates under full project rules — no relaxation because FSD is autonomous:
@@ -209,6 +224,7 @@ This skill is intentionally a **thin alias**. It does NOT duplicate:
209
224
  - Retrospective analysis (owned by `homework`)
210
225
  - PR merge execution (owned by `mgr-gitnerd`)
211
226
  - Completion verification (owned by R020 + `goal`)
227
+ - Loop driving itself — the main conversation may run the iteration inline (see 「인라인 실행 허용」); `goal`/`omcustom-loop` are optional expressions of the same contract
212
228
 
213
229
  If any of those underlying skills evolve, FSD automatically benefits — its only responsibility is declaring the intent and forwarding to the right components.
214
230
 
@@ -50,19 +50,25 @@ Parse arguments:
50
50
 
51
51
  Attempt deterministic transcript extraction. Preferred sources (in order):
52
52
 
53
- 1. **Grep for rule-violation markers** in the current conversation context:
53
+ 1. **advisor 판정 재사용 계수 스크립트 (1순위, #1683 #2)** — 트랜스크립트 경로를 알 수 있으면 먼저 실행합니다:
54
+ ```bash
55
+ bash scripts/count-r007-r008.sh "$TRANSCRIPT" --json
56
+ ```
57
+ 이 스크립트는 `.claude/hooks/scripts/r007-r008-drift-advisor.sh`를 턴 단위로 호출해 R007 헤더 누락·R008 접두사 누락 건수를 **훅과 동일한 판정식**으로 셉니다. 자체 정규식으로 재구현하지 않습니다 — v1.1.64 세션에서 자가 계수가 3회 연속 방법 오류(레코드 분리 미인지, 병합 키 불일치, 중첩 중복 계상)로 실패한 것이 기원이며, R020 「자가 계수는 advisor 판정식을 재현한다」가 규범입니다. 스크립트가 없거나 실패하면 아래 소스로 내려가되, 회고에 "advisor 재사용 계수 미수행"을 명시합니다.
58
+
59
+ 2. **Grep for rule-violation markers** in the current conversation context:
54
60
  - Safety classifier trip signals: `[Safety]`, `[R001]`, `[Warning]`, classifier denial messages
55
61
  - Self-corrections: "sorry", "I made an error", "let me correct", "이전 답변 수정", "죄송합니다"
56
62
  - Premature hypothesis signals: "I assume", "probably", "should be" followed by a contradiction in a later turn
57
63
  - Interrupt + re-plan events: user corrections, "no", "wrong", "다시", "아니"
58
64
 
59
- 2. **Transcript files** (CC v2.1.x session JSONL):
65
+ 3. **Transcript files** (CC v2.1.x session JSONL):
60
66
  ```bash
61
67
  find ~/.claude/projects -name "session-*.jsonl" -newer "$(date -v-1d +%Y-%m-%dT00:00:00)" 2>/dev/null | head -5
62
68
  ```
63
69
  Parse `type: "error"`, `type: "correction"`, `type: "feedback"` events.
64
70
 
65
- 3. **Fallback**: Rely on the model's recall of the current conversation (impressionistic, lower confidence — mark findings as `[recall]` not `[transcript]`).
71
+ 4. **Fallback**: Rely on the model's recall of the current conversation (impressionistic, lower confidence — mark findings as `[recall]` not `[transcript]`).
66
72
 
67
73
  #### 2b. Linked Previous Sessions (when `--days` > 0)
68
74
 
@@ -224,7 +230,8 @@ This skill does NOT use `context: fork`. The fork cap is at 10/12; homework is a
224
230
 
225
231
  ## Limitations
226
232
 
227
- - **Transcript availability**: CC `session-*.jsonl` schema may change; Phase 2a source (1) grep is more resilient than JSONL parsing.
233
+ - **Transcript availability**: CC `session-*.jsonl` schema may change; Phase 2a source (2) grep is more resilient than JSONL parsing.
228
234
  - **Recall accuracy**: When transcript files are unavailable, findings are marked `[recall]` and confidence is lower.
229
235
  - **episodic-memory dependency**: `--days` mode degrades gracefully when the plugin is unavailable (falls back to JSONL scan).
230
236
  - **Scope**: This skill analyzes session behavior, not code quality. For code-quality retrospectives, use `dev-review` or `adversarial-review`.
237
+ - **Count fidelity**: only the advisor-reuse script (2a source 1) reproduces the hook verdict; sources 2–4 are approximations and must be labeled as such in the retrospective.
@@ -1,5 +1,5 @@
1
1
  {
2
- "version": "1.1.66",
2
+ "version": "1.1.68",
3
3
  "lastUpdated": "2026-09-03",
4
4
  "omcustomMinClaudeCode": "2.1.121",
5
5
  "omcustomMinClaudeCodeReason": "Sensitive-path direct Write/Edit on .claude/** under bypassPermissions (R010 deprecation, #1101)",