@kaydash9999/banker-plugins 0.6.0 → 0.7.0

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.
@@ -6,7 +6,7 @@
6
6
  },
7
7
  "metadata": {
8
8
  "description": "Claude Code skills + commands — QA, audit, docs, architecture, dependency setup, and wiki; the banker plugin marketplace.",
9
- "version": "0.6.0"
9
+ "version": "0.7.0"
10
10
  },
11
11
  "plugins": [
12
12
  {
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "banker",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "Claude Code plugin: QA/audit/docs/architecture skills + commands, a /banker:setup installer for OS dependencies (playwright, etc.), and wiki compaction.",
5
5
  "author": {
6
6
  "name": "smallOpenSource",
package/CHANGELOG.md CHANGED
@@ -1,5 +1,20 @@
1
1
  # Changelog
2
2
 
3
+ ## [0.7.0] - 2026-07-16
4
+
5
+ ### Added
6
+ - **신규 스킬 6종** (전부 `target: both`). 배포용이므로 "이 저장소에서 재보니 무동작"류 판정은 설계 근거로 쓰지 않았다. 각 스킬의 사실 주장은 게시 전 적대적 검증에 걸었고, 거기서 반증된 것(검증되지 않은 표준 번호·법령 API 엔드포인트·트래커 이슈 인용·출처 없는 수치)은 그럴듯해도 넣지 않았다. 검증이 실제로 적출한 것들: `update-banker` 가 sweep 대상을 절반만 적은 것(스킬만 적고 command 프롬프트를 빠뜨림), `refresh-readme` 의 드리프트 예시가 디렉터리 카운트(49)를 스킬 수(48)로 오기한 것, `codex/transform-matrix.md` 가 DISPUTED 항목을 확정으로 서술한 것. 셋 다 게시 전에 고쳤다.
7
+ - `ultra-interview`: 리서치를 선행해 공개 정보(공식 문서·규정·법령·시행세칙·기록)가 답할 수 있는 것은 사람에게 묻지 않고, 모호성 3% 이하까지 인터뷰한다. **모호도를 이산 체크리스트(미해결/전체)로 계측**하는 것이 설계 요점이다. 스칼라 자기채점 위에서는 3%가 표현되지 않는다(자기신뢰도 응답이 라운드넘버 소수에 뭉치고, 가중치 합이 1인 공식에서는 전 축 0.95여도 모호도가 정확히 0.05라 통과하려면 어딘가에 완벽을 선언해야 한다). 이산 계측은 셈이라 부풀릴 수 없다. Evidence/Inference/Preference 3분류로 Preference 만 질문한다. OMC/OMX 네이티브 `deep-interview` 를 번들하거나 대체하지 않으며, **자체 루브릭을 소유**한다(OMC 3차원 대 OMX 5차원이라 네이티브 채점을 물려받으면 같은 임계값이 런타임마다 다른 뜻이 된다).
8
+ - `interval-report`: 장기 수행의 중간 보고를 `docs/intermission.md` 로 갱신한다. 측정 범위는 **마지막 사용자 지시로 시작된 현재 수행분**이고 시작 시각은 그 시점이다. **시작 시각을 파일에 영속하고 절대 재스탬프하지 않는다**. compaction/resume 후 now 로 다시 찍으면 elapsed 가 0으로 붕괴해 리포트가 가장 필요한 순간에 가장 낙관 편향된다. 시각은 `date` 로 실측한다(두 런타임 모두 컨텍스트에 시:분이 없다). ultragoal 이 있으면 읽고 없어도 동작하며 상태를 복제하지 않는다. compaction 트리거는 `smart-compact` 소관으로 남긴다.
9
+ - `summary-wiki`: 위키를 `docs/` 하위 단일 파일로 개조식 요약해 **사용자가 아는 지식과 위키에 쌓인 내용의 차이를 식별**하게 한다(sync 검토). **`wiki_list` 를 쓰지 않고 파일을 직접 열거**하는 것이 핵심이다. `wiki_list` 는 구조적으로 stale 한 인덱스를 읽어 페이지를 조용히 누락하며(실측: 직접 열거 17 대 `wiki_list` 16), 그 누락은 성공을 보고하면서 이 스킬의 목적을 정확히 배반한다. 위키에는 쓰지 않는다(`compact-wiki` 는 제자리 파괴적 변형이라 별개). `개조식` 은 어문규범에 명명된 문체가 아니므로 "관행 준수"로 서술한다.
10
+ - `update-banker`: 설치된 banker 를 최신 배포본으로 갱신한다. **축은 OS 가 아니라 채널**이다(banker 는 dependencies 0 에 복사 설치라 OS 분기가 거의 없고, Claude 플러그인·npm 전역 CLI·Codex 스킬 3채널이 서로 다른 메커니즘으로 독립 드리프트한다). **npm 을 먼저 올리고 검증한 뒤에만 `banker setup --codex`** 를 돌린다. setup 은 복사 전에 모든 `banker-*` 를 쓸어내므로 구버전 CLI 로 실행하면 그 구버전 매니페스트 수만큼만 복원된다. 판정은 exit code 가 아니라 채널별 프로브 재실행으로 한다.
11
+ - `refresh-readme`: 코드가 바뀌어 README 가 작성 시점에 머무는 것을 조치한다. README 산문 주장을 매니페스트·`skills/`·`package.json` 과 대조하는 삼각검증이 신규 능력이다. 펜스·인라인 코드·URL·`--flag` 를 인지한다(POSIX end-of-options ` -- ` 는 산문 이중하이픈과 문자적으로 동일해 일괄 치환은 그 자체로 결함이며, 실제로 문서화된 MCP 설치 명령을 깨뜨린다). AI 문체 마커는 `humanizer` 에 위임하고 재서술하지 않는다.
12
+ - `cleansing-memory`: 메모리 파일을 문서화된 threshold 내로 정리한다(중복 최신본화, 무손실 압축, append 대 replace 판별). **문서화된 하드 게이트는 `MEMORY.md` 의 200줄 OR 25KB 하나뿐이고 `CLAUDE.md` 에는 문서화된 크기 한도가 없다**. 바이트 캡을 제시하는 것은 날조다. Codex 의 `project_doc_max_bytes`(32768) 는 프로젝트 스코프 `AGENTS.md` 에만 걸리고 전역 파일에는 적용되지 않으며, raw 바이트를 자른 뒤 lossy UTF-8 디코드를 하므로 정확히 N바이트로 자르면 한글 경계 문자가 손상된다. auto-memory topic 파일이 시작 시 로드되지 않는다는 문서화된 성질이 append→replace 최적화의 근거다. 코드베이스 유도분 트림은 Claude 의 `/doctor` 에 위임한다.
13
+
14
+ ### Changed
15
+ - Codex 설치 스킬 수 **42 → 48**(+커맨드 2 유지, claude-only=0). `codex/manifest.json`·`README.md`·`codex/transform-matrix.md`·`scripts/smoke-test.js`·`.github/workflows/harness-setup-ci.yml` 을 동기화했다.
16
+ - **`scripts/smoke-test.js` 에 집합 동등성 단언을 추가**했다(실설치 실행 **앞**). `codex/manifest.json` 의 skill 이름 집합과 `skills/` 디스크 집합이 같은지 검사하고 불일치를 `manifest-only` / `disk-only` 로 **이름을 찍어** 보고한다. 기수 단언만으로는 이 결함을 잡을 수 없다. dry-run 카운터는 파일시스템이 아니라 매니페스트를 순회하므로, 디렉터리가 없어도 매니페스트 줄 수만 맞으면 통과하고 실설치는 복사 중 ENOENT 로 죽어 `HARNESS ERROR` 라는 환경 문제처럼 보이는 메시지만 남긴다. 이 단언은 지금까지 아무 장치도 없던 반대 방향(디스크에 있으나 매니페스트에 없어 Claude 에만 실리고 Codex 로는 영영 가지 않는 조용한 claude-only 스킬)도 함께 닫는다. 릴리스마다 하드코딩 이름 배열을 덧붙이던 방식을 이 단언 하나로 대체한다.
17
+
3
18
  ## [0.6.0] - 2026-07-15
4
19
 
5
20
  ### Added
package/README.md CHANGED
@@ -7,7 +7,7 @@
7
7
 
8
8
  [빠른 시작](#빠른-시작) · [구성](#구성) · [설치 상세](#설치-상세-npm--codex) · [요구사항](#요구사항) · [업데이트 / 제거](#업데이트--제거) · [라이선스 / 서드파티](#라이선스--서드파티)
9
9
 
10
- banker는 QA, 보안 감사, 문서, 아키텍처, 위키 작업을 위한 스킬 42개와 의존성·개발환경(OS별) 설치 스킬을 묶은 Claude Code 플러그인입니다. 설치하면 스킬과 커맨드가 `/banker:<이름>` 네임스페이스로 노출됩니다. 이 저장소 자체가 Claude Code 마켓플레이스(`.claude-plugin/marketplace.json`)이자 플러그인(`.claude-plugin/plugin.json`, name `banker`)이며, 도구에 무관한 스킬은 Codex CLI에도 설치됩니다.
10
+ banker는 QA, 보안 감사, 문서, 아키텍처, 위키 작업을 위한 스킬 48개와 의존성·개발환경(OS별) 설치 스킬을 묶은 Claude Code 플러그인입니다. 설치하면 스킬과 커맨드가 `/banker:<이름>` 네임스페이스로 노출됩니다. 이 저장소 자체가 Claude Code 마켓플레이스(`.claude-plugin/marketplace.json`)이자 플러그인(`.claude-plugin/plugin.json`, name `banker`)이며, 도구에 무관한 스킬은 Codex CLI에도 설치됩니다.
11
11
 
12
12
  > npm 패키지(`@kaydash9999/banker-plugins`)와 GitHub 저장소(`smallOpenSource/banker_plugins`)는 같은 메인테이너가 관리합니다.
13
13
 
@@ -85,6 +85,12 @@ playwright(브라우저 QA)나 oh-my-claudecode(OMC/OMX)처럼 별도 의존성
85
85
  | `ralph-qa` | 작업 결과를 다른 LLM·별도 세션으로 독립 교차검증 반복 |
86
86
  | `smart-compact` | 컨텍스트 임계 초과 시 위키·resume 저장 게이트 자동 무장 |
87
87
  | `deep-research` | 다중 소스 팬아웃 + 적대적 검증 인용 리서치 |
88
+ | `ultra-interview` | 리서치 선행으로 사람 질문 최소화, 모호성 3% 이하까지 인터뷰 |
89
+ | `interval-report` | 장기 수행 중간 보고를 `docs/intermission.md` 로 갱신(경과·잔여·단일 표) |
90
+ | `summary-wiki` | 위키를 `docs/` 단일 파일 개조식으로 요약(지식 동기화 검토용, 읽기 전용) |
91
+ | `update-banker` | 설치된 banker 를 3채널(Claude·npm·Codex) 순서 게이트로 최신화 |
92
+ | `refresh-readme` | 코드와 어긋난 README 를 현재 상태에 맞게 갱신(드리프트 해소) |
93
+ | `cleansing-memory` | 메모리 파일을 문서화된 threshold 내로 정리(중복 최신본화·무손실 압축) |
88
94
 
89
95
  ### 스킬: 개발환경 setup (OS별 · 런타임별)
90
96
 
@@ -128,7 +134,7 @@ banker uninstall # 제거
128
134
 
129
135
  - `--scope project` 로 프로젝트 로컬(`./.codex`)에 설치하고, `--dry-run` 으로 미리 볼 수 있습니다.
130
136
  - non-root 전용입니다(전역 sudo 설치 시 root 소유 파일을 방지). postinstall이 없으므로 `banker setup` 을 직접 실행합니다.
131
- - Codex에는 스킬 42개가 `~/.codex/skills/banker-<name>/` 에, 커맨드 2개가 `~/.codex/prompts/banker-<name>.md` 에 설치됩니다(`codex/manifest.json`). 디렉터리명과 일치하도록 프론트매터 `name:` 이 `banker-<name>` 으로 재작성되어 Codex가 `banker-<name>` 으로 인식합니다.
137
+ - Codex에는 스킬 48개가 `~/.codex/skills/banker-<name>/` 에, 커맨드 2개가 `~/.codex/prompts/banker-<name>.md` 에 설치됩니다(`codex/manifest.json`). 디렉터리명과 일치하도록 프론트매터 `name:` 이 `banker-<name>` 으로 재작성되어 Codex가 `banker-<name>` 으로 인식합니다.
132
138
  - OMC/Claude 에 결합됐던 오케스트레이터·설치·유틸 표면(all-in-one·ultra-init·front-qa·setup·setup-omc·setup-omc-hud·setup-stitch·omc-reference·compact-copy)은 본문이 **런타임 인식**이라 Codex에서도 동작합니다 — Codex에선 OMC 대신 **oh-my-codex(OMX)** 의 동명 스킬(ralplan·ralph·ultraqa·hud 등)과 `codex mcp`·내장 `/copy` 를 사용합니다(Codex는 `omx setup` 전제).
133
139
  - `~/.codex/AGENTS.md` 는 건드리지 않습니다(omx가 재생성하므로 `~/.codex/skills/` 자동 검색에 의존).
134
140
 
@@ -50,6 +50,13 @@
50
50
 
51
51
  { "name": "obsidizer", "type": "skill", "target": "both", "reason": "AI-wiki -> Obsidian graph normalize/interlink; LLM semantic edits + zero-input deterministic canonicalizer, runtime-agnostic; in-place durable", "supportingFiles": ["obsidize.mjs"], "caveat": "OMC-managed trees: 9-field frontmatter envelope + reserved files + no-rename + bare [[slug]] links only (extractWikiLinks slugifies piped/heading forms -> broken-ref); aliases written in generic vaults only; Canvas sidecars and body-inline :: are durable in-place; uses wiki_lint read-only. --enable is Claude-only (Codex has no MCP tool hooks) and is an honest no-op on Codex." },
52
52
 
53
+ { "name": "ultra-interview", "type": "skill", "target": "both", "reason": "research-first interview that resolves what public sources can answer and asks the human only what they alone can decide; discrete checklist gate (unresolved/total) instead of a scalar self-score", "supportingFiles": [], "caveat": "does NOT bundle or replace the OMC/OMX native deep-interview. Owns its own rubric on purpose: OMC scores 3 dimensions and OMX scores 5, so inheriting a native score would make the same threshold mean different things per runtime. Regulatory lookup is a general 'find the jurisdiction's primary source' instruction, not a hardcoded endpoint." },
54
+ { "name": "interval-report", "type": "skill", "target": "both", "reason": "human-facing progress ledger at docs/intermission.md for long runs; thin time layer + renderer over whatever state exists", "supportingFiles": [], "caveat": "start time is persisted in the file and never re-stamped (a compaction/resume re-stamp collapses elapsed to 0 and biases the report optimistic exactly when it matters most). Wall-clock comes from `date` because neither runtime exposes hour:minute in context. Reads ultragoal state when present but never duplicates it; leaves compaction triggering to smart-compact." },
55
+ { "name": "summary-wiki", "type": "skill", "target": "both", "reason": "read-only digest of the wiki into a single docs/ file for a knowledge-sync review (what the user knows vs what the wiki accumulated)", "supportingFiles": [], "caveat": "Claude = wiki_* MCP over .omc/wiki; Codex = `omx wiki` CLI over omx_wiki/ (there is NO wiki_* MCP on Codex; do not copy the append_wiki/compact-wiki caveat wording). Enumerates .omc/wiki/*.md directly and never wiki_list, which reads a structurally stale index and silently omits pages. Read-only toward the wiki; distinct from compact-wiki, which mutates it in place." },
56
+ { "name": "update-banker", "type": "skill", "target": "both", "reason": "updates an installed banker across its three independently-drifting channels (Claude plugin / npm global CLI / Codex skills)", "supportingFiles": [], "caveat": "the axis is channel, not OS: banker has zero dependencies and copy-based install, so OS differences reduce to npm prefix/EACCES footnotes. npm must be updated FIRST and verified before `banker setup --codex`, because setup sweeps every banker-* before copying and a stale CLI restores only its own older manifest. Verdicts come from per-channel probes, never exit codes." },
57
+ { "name": "refresh-readme", "type": "skill", "target": "both", "reason": "brings a README back in line with the code it drifted from, before release; prose claims are cross-checked against the manifest, skills/, and package.json", "supportingFiles": [], "caveat": "README only. Fence/inline-code/URL/--flag aware: POSIX end-of-options ` -- ` is textually identical to prose double-hyphen, so a blanket sed/awk substitution is itself a defect. Delegates AI-writing markers to humanizer rather than restating them." },
58
+ { "name": "cleansing-memory", "type": "skill", "target": "both", "reason": "keeps agent memory files inside their documented thresholds by de-duping to latest, condensing losslessly, and converting append-style records into replace-style", "supportingFiles": [], "caveat": "only MEMORY.md has a documented hard gate (200 lines or 25KB, whichever comes first); CLAUDE.md has NO documented size limit, so asserting a byte cap for it would be fabrication. Codex's 32768-byte project_doc_max_bytes covers project-scope AGENTS.md only, not the global one, and truncates raw bytes before a lossy UTF-8 decode, so cutting to an exact byte count corrupts the boundary character. Codebase-derivable CLAUDE.md trimming is left to Claude's own /doctor." },
59
+
53
60
  { "name": "front-qa", "type": "command", "target": "both", "reason": "ralplan->ralph frontend-QA pipeline; Claude=OMC, Codex=OMX", "supportingFiles": [] },
54
61
  { "name": "setup", "type": "command", "target": "both", "reason": "installer orchestrator; Claude AskUserQuestion multi-select, Codex prompt-based selection", "supportingFiles": [] }
55
62
  ]
@@ -40,3 +40,11 @@ The generator (`banker setup --codex`) applies the rules below for `target: both
40
40
  - `deep-research` — needs web search/fetch (Claude WebSearch/WebFetch or bundled workflow; Codex OMX autoresearch).
41
41
  - `smart-compact` — Claude statusLine exposes context%; Codex signal unconfirmed → heuristic fallback; `/copy`·`/compact`·paste stay user-driven (TUI).
42
42
  - `obsidizer` — OMC-managed trees respect the 9-field frontmatter whitelist + reserved files + no-rename + bare `[[slug]]` links only; `aliases` are written in generic vaults only; Canvas sidecars and body-inline `::` are durable in-place; no `wiki_*` write dependency, `wiki_lint` read-only for verification. `--enable` is Claude-only (plugin-declared PostToolUse hook); Codex has no MCP tool hooks → honest no-op.
43
+
44
+ 신규 스킬(0.7.0)도 `both`·런타임 인식:
45
+ - `ultra-interview` → 리서치 선행 질문 최소화 + 모호성 3% 이하 종료. **자체 루브릭 소유**가 설계 요점이다: OMC deep-interview 는 3차원, OMX 는 5차원으로 산식이 달라 네이티브 채점을 물려받으면 같은 임계값이 런타임마다 다른 뜻이 된다. OMC/OMX 네이티브 `deep-interview` 를 번들하거나 대체하지 않는다. 규제 조회는 엔드포인트 하드코딩이 아니라 "해당 관할의 공식 1차 출처를 찾아라"는 일반 지시다.
46
+ - `interval-report` → 런타임 무관(순수 파일+`date`). 두 런타임 모두 컨텍스트에 시:분이 없어 `date` 실측이 필요하다. ultragoal 산출물은 Claude=`.omc/ultragoal/`, Codex=`.omx/ultragoal/` 로 경로만 다르고, 있으면 읽고 없어도 동작한다.
47
+ - `summary-wiki` → **위키 접근이 런타임마다 완전히 다르다.** Claude=`wiki_*` MCP on `.omc/wiki/`, Codex=`omx wiki <tool> --input <json> --json` CLI on **`omx_wiki/`**(repo 레벨). **Codex 에 `wiki_*` MCP 는 없다.** `append_wiki`·`compact-wiki` 의 기존 caveat 문구를 복붙하면 오정보다. OMX 에만 있는 `wiki_refresh` 로 stale-index 를 고칠 수 있다.
48
+ - `update-banker` → 축이 OS 가 아니라 **채널**이다. Claude 런타임 = `claude plugin update` 후 프로브로 전진 확인, 안 움직이면 `claude plugin marketplace update` 를 더한다("항상 2단계"인지는 **DISPUTED** 이므로 확정으로 쓰지 않는다). Codex 런타임 = claude 분기 스킵, npm 갱신 후 `banker setup --codex`. 공통 = npm-first 순서 게이트(구버전 CLI 로 setup 하면 sweep 후 그 구버전 매니페스트 수만큼만 복원된다)와 채널별 독립 프로브 검증. 채널 부재는 에러가 아니라 스킵이다.
49
+ - `refresh-readme` → 런타임 무관(파일 읽기·쓰기뿐, 의존성 0). 안티슬롭 마커는 `humanizer` 에 위임하고 재서술하지 않는다.
50
+ - `cleansing-memory` → **두 런타임의 메모리 모델이 거의 안 닮았다.** Claude = `CLAUDE.md`(문서화된 한도 없음) + `MEMORY.md`(200줄 OR 25KB 하드 게이트) + `@path` 4홉 import + AGENTS.md 미지원. Codex = `AGENTS.md` 프로젝트 스코프 32768B(`project_doc_max_bytes`) + 전역 `~/.codex/AGENTS.md` 무제한. Codex 는 raw 바이트를 자른 뒤 lossy UTF-8 디코드를 하므로 한글 경계 문자가 깨진다. Claude 의 코드베이스 유도분 트림은 `/doctor` 에 위임한다.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kaydash9999/banker-plugins",
3
- "version": "0.6.0",
3
+ "version": "0.7.0",
4
4
  "description": "banker — Claude Code + Codex CLI plugin (QA, audit, docs, architecture, wiki skills). Install via Claude Code marketplace, or `npm i -g @kaydash9999/banker-plugins` then `banker setup`.",
5
5
  "bin": {
6
6
  "banker": "bin/banker.js"
@@ -0,0 +1,150 @@
1
+ ---
2
+ name: cleansing-memory
3
+ description: "(banker) 에이전트 메모리 파일(MEMORY.md·CLAUDE.md·AGENTS.md)을 문서화된 threshold 안으로 정리: 중복 최신본화, 무손실 간결화, append→replace 판별. 'cleansing-memory'/'메모리 정리'/'MEMORY.md 정리'/'CLAUDE.md 압축'/'AGENTS.md 용량' 시 사용."
4
+ ---
5
+
6
+ # cleansing-memory: 메모리 파일 정리 (중복 최신본화·무손실 압축·replace 판별)
7
+
8
+ 에이전트 런타임이 세션 시작마다 읽는 메모리 파일(Claude `MEMORY.md`·`CLAUDE.md`, Codex `AGENTS.md`)은
9
+ 세션을 거듭할수록 **쌓이기만 한다.** 이 스킬은 그 파일들을 **관리 기준 threshold 안으로** 되돌린다:
10
+ (1) 중복을 정리해 **최신본만** 남기고, (2) 과도한 장문을 **내용 유실 없이** 간결화하고,
11
+ (3) **append 가 아니라 replace 로 관리할 정보를 판별**한다.
12
+
13
+ 다루는 수치는 **문서화된 것만**이다. 한도가 문서화되지 않은 파일에는 한도를 지어내지 않는다.
14
+
15
+ **런타임:** 두 런타임의 메모리 모델은 **거의 닮지 않았다.** 한쪽 규칙을 다른 쪽에 옮기면 틀린다.
16
+ Claude = `CLAUDE.md` 한도 없음 + `MEMORY.md` 200줄/25KB + `@path` 4홉 import + AGENTS.md 미지원.
17
+ Codex = `AGENTS.md` 32768 B 프로젝트 예산 + 전역 파일 캡 없음.
18
+ 그래서 이 스킬은 파일마다 **그 파일에 문서화된 한도만** 적용한다. 공통 규칙을 만들지 않는다.
19
+
20
+ ## When to use
21
+ - 메모리 파일이 커져 **시작 컨텍스트**를 잠식할 때.
22
+ - 세션이 쌓여 같은 사실의 **옛 버전과 새 버전이 공존**할 때(상충 지시).
23
+ - Codex 프로젝트 `AGENTS.md` 체인이 **32768 B 에 근접·초과**해 조용히 잘릴 때.
24
+ - Claude auto-memory `MEMORY.md` 가 **200줄 또는 25KB 에 근접**할 때.
25
+ - dual-runtime 저장소에서 Claude 쪽과 Codex 쪽 메모리 파일이 **서로 다른 사실**을 말할 때.
26
+
27
+ ## When NOT to use
28
+ - **아직 안 쓴 지식을 남기려는 것** → OMC `remember`. 경계가 헷갈리기 쉬우니 분명히 한다:
29
+ `remember` 는 **쓰기 측**(무엇을 기억할지 결정해 남긴다), cleansing-memory 는 **GC 측**(이미 쌓인 걸 정리한다).
30
+ `remember` 에는 크기·dedup 메커닉이 **0** 이다. 남길 거면 remember, 남은 걸 줄일 거면 이 스킬.
31
+ - **Claude 에서 코드베이스 유도분 트림** → `/doctor` 가 v2.1.206+ 에서 **이미 제안한다. 그쪽을 쓰라.**
32
+ (디렉터리 구조·의존성 목록·아키텍처 개요처럼 코드베이스에서 유도 가능한 내용.) 여기서 재구현하지 않는다.
33
+ 단 `/doctor` 는 **Claude 전용**이라 Codex 의 `AGENTS.md` 엔 대체재가 없다.
34
+ - **한도에 여유가 큰 파일** → 손대지 마라. 압축은 공짜가 아니라 정보 손실 위험을 감수하는 행위다.
35
+
36
+ ## threshold (검증된 것만)
37
+ 확인 시점: **2026-07-16 / codex-cli 0.142.5 / Claude Code 2.1.211.**
38
+
39
+ | 파일 | 문서화된 한도 |
40
+ |---|---|
41
+ | Claude `MEMORY.md` | **200줄 OR 25KB 중 먼저.** 유일한 문서화된 하드 로드 게이트 |
42
+ | Claude `CLAUDE.md` | **없음.** 문서: "길이와 무관하게 전부 로드". 200줄은 soft target |
43
+ | Codex `AGENTS.md` (프로젝트) | **32768 B (32 KiB)** = `project_doc_max_bytes` 기본값 |
44
+ | Codex `~/.codex/AGENTS.md` (전역) | **캡 없음.** 별도 provider 가 통째로 read |
45
+ | agents.md 스펙 | **없음.** 파일명·중첩·마크다운만 표준화 |
46
+
47
+ - **CLAUDE.md 에 캡을 제시하면 날조다.** 문서화된 바이트 한도가 존재하지 않는다.
48
+ 정직한 진술은 "크면 줄이는 게 낫다"까지고, "N 을 넘으면 잘린다"는 **거짓**이다.
49
+ - **스코프 오류 주의**: 25KB 는 `MEMORY.md` **단독**에 걸린다. auto-memory **디렉터리 합계가 아니다.**
50
+ - **바이트가 맞고 토큰은 틀리다**: 런타임이 강제하는 건 바이트, 그리고 줄-OR-바이트다.
51
+ - **버전 고정 주의**: 32768·25KB/200줄·4홉은 **전부 버전 고정 사실**이다. 커뮤니티 출처는 **이미** 서로
52
+ 불일치한다(import 깊이를 4홉보다 크게 적은 글이 돌아다닌다). 보고할 때 **확인 시점을 같이 적고**,
53
+ 다른 버전에서는 1차 출처로 재확인하라.
54
+
55
+ ## 메커니즘 (모르면 안전하게 못 자른다)
56
+ - **CLAUDE.md 로드 순서**(전부 concat, **override 없음**): managed policy → user `~/.claude/CLAUDE.md`
57
+ → project `./CLAUDE.md` 또는 `./.claude/CLAUDE.md` → local `./CLAUDE.local.md`.
58
+ 뒤가 앞을 덮지 않는다. **더해진다.** "뒤에 쓴 게 이긴다"고 가정하면 상충이 안 지워진다.
59
+ - **`@path` import 재귀 깊이 = 4홉.** 코드 스팬·펜스 안의 `@README` 는 **리터럴**이라 import 되지 않는다.
60
+ - **Claude Code 는 AGENTS.md 를 읽지 않는다.** 문서화된 interop = CLAUDE.md 에 `@AGENTS.md` import 또는
61
+ 심볼릭 링크. dual-runtime 저장소에서 AGENTS.md 만 고치면 **Claude 쪽엔 아무 효과가 없다.**
62
+ - **Codex 프로젝트 discovery**: 루트→cwd 순회, **디렉터리당 첫 매칭 파일명 하나만**. 루트부터 concat.
63
+ - **`project_doc_max_bytes = 0` 이면 AGENTS.md 프로젝트 문서 로딩이 완전히 꺼진다.**
64
+ - **auto-memory 위치**: `~/.claude/projects/<project>/memory/`. git repo 기준이라 worktree 가 공유한다.
65
+ `autoMemoryDirectory` 로 변경, `autoMemoryEnabled:false` 또는 `CLAUDE_CODE_DISABLE_AUTO_MEMORY=1` 로 비활성.
66
+ 기본 켜짐·머신 로컬.
67
+
68
+ ## 워크플로
69
+
70
+ ### 1. 인벤토리 (읽기 전용)
71
+ 대상과 **실제 크기**를 먼저 잰다. 추정 금지.
72
+ - Claude: `~/.claude/CLAUDE.md`, `./CLAUDE.md` 또는 `./.claude/CLAUDE.md`, `./CLAUDE.local.md`,
73
+ managed policy, auto-memory `MEMORY.md`.
74
+ - Codex: `~/.codex/AGENTS.md`(캡 없음), 프로젝트 루트→cwd 의 `AGENTS.md` 체인.
75
+
76
+ ```bash
77
+ wc -lc <파일> # 줄 수와 바이트를 같이 본다. 문자 수(-m)가 아니라 바이트다
78
+ ```
79
+ - `@path` import 를 **4홉까지** 따라가 실제 로드 총량을 본다. 코드 스팬·펜스 안의 `@...` 는 세지 마라.
80
+ - **한도에 여유가 크면 여기서 멈춘다.** 보고만 하고 끝낸다.
81
+
82
+ ### 2. 중복 정리 → 최신본만
83
+ 1차 근거: 공식문서가 **"메모리 파일 간 상충하는 지시"** 를 주기적 검토가 필요한 **실패 모드로 명시**한다.
84
+ 커뮤니티 heuristic 이 아니라 문서화된 실패 모드다.
85
+ - 같은 사실의 항목이 여럿이면 **최신본 하나만** 남기고 옛 값은 지운다.
86
+ - 로드 체인은 override 가 없으니, user 와 project 가 상충하면 **둘 다 살아서** 모델에 들어간다.
87
+ 직접 지워야 사라진다.
88
+ - 어느 쪽이 최신인지 **모르면 지우지 말고 물어라.** 모르고 지우는 건 정리가 아니라 도박이다.
89
+
90
+ ### 3. append→replace 판별 (이 스킬의 알맹이)
91
+ - **replace 대상 = 현재 상태를 서술하는 사실**(버전·설치 위치·진행 지점). 새 값이 옛 값을 **무효화**한다
92
+ → 덮어쓴다. 이력을 남기려고 append 하면 파일이 단조 증가하고 모델은 **옛 값도 사실로 읽는다.**
93
+ - **append 대상 = 일어난 사건의 기록**(감사 결과·결정 근거). 나중 사건이 앞 사건을 무효화하지 않는다
94
+ → 쌓되 요약해 topic 파일로 민다.
95
+ - 애매하면 질문 하나로 가른다: **"새 값이 나오면 옛 값은 틀린 것이 되나?"** 그렇다 → replace.
96
+ 둘 다 여전히 참이다 → append.
97
+
98
+ ### 4. 무손실 간결화 + topic 파일 분산
99
+ 살아남은 최적화는 이것이다. **auto-memory topic 파일은 시작 시 로드되지 않는다**(문서화된 메커니즘).
100
+ `MEMORY.md` **만** 로드된다.
101
+ - → `MEMORY.md` 인덱스는 **얇게**, 상세는 **topic 파일로** 민다. 정보는 그대로 두고 **시작 컨텍스트
102
+ 비용만 실제로 제거**한다. 삭제가 아니라 **이동**이라 무손실이다.
103
+ - → 200줄/25KB 게이트도 `MEMORY.md` **단독**에 걸리므로 이동만으로 통과한다.
104
+ - 간결화는 **표현**을 줄이는 것이지 **사실**을 줄이는 게 아니다. 서술을 줄이고 구체값(버전·경로·수치·결정)은
105
+ 남긴다.
106
+ - 이 스킬이 소유하는 연산은 셋뿐이다: **중복 최신본화 + 무손실 압축 + append→replace 판별.**
107
+ Claude 의 코드베이스 유도분 트림은 `/doctor` 몫이다(위 "When NOT to use").
108
+
109
+ ### 5. 안전한 쓰기
110
+ - **문자 경계에서 자르고 한도에 여유를 둔다.** 정확히 N 바이트로 맞추지 마라("함정" 참조).
111
+ - 쓰기 전에 diff 를 보여주거나 원본을 백업한다. 메모리 파일 손실 = **세션 간 지식 손실**이다.
112
+ - `project_doc_max_bytes = 0` 으로 "해결"하지 마라. 로딩이 통째로 꺼진다.
113
+ - AGENTS.md 만 고치고 Claude 도 좋아졌다고 하지 마라. **Claude Code 는 AGENTS.md 를 읽지 않는다.**
114
+
115
+ ### 6. 검증 (보고 의무)
116
+ 쓰고 나서 **다시 재고** 보고한다. 추정 금지.
117
+ - **before/after 바이트·줄 수**를 파일별로. 토큰이 아니라 바이트다.
118
+ - 한도 대비: `MEMORY.md` 200줄 OR 25KB, 프로젝트 `AGENTS.md` 체인 32768 B.
119
+ - **UTF-8 무결성**: 결과 파일에 **U+FFFD** 가 있는지 확인한다. 있으면 절단이 문자를 쪼갠 것이다. 되돌려라.
120
+ - **유실 점검**: replace 로 지운 게 정말 무효화된 옛 값인지, topic 파일로 민 내용이 **실제로 거기 있는지**.
121
+ - **확인 시점 명시**: 기준 수치는 codex-cli 0.142.5 / Claude Code 2.1.211 (2026-07-16).
122
+ - **자가 무효화 위험**을 보고에 적는다("함정" 참조).
123
+
124
+ ## 함정
125
+ - **UTF-8 손상 (Codex)**: Codex 는 **raw 바이트 버퍼를 자르고 나서** `from_utf8_lossy` 를 씌운다.
126
+ 한글은 **3바이트/자**라 경계 문자가 쪼개져 **U+FFFD 로 깨진다.** 절단은 **조용하고 파일 중간**에서
127
+ 일어나며 TUI 에 **경고가 뜨지 않는다.** → "정확히 N 바이트로 자르는" 방식은 **스스로 손상을 만든다.**
128
+ 반드시 **문자 경계에서 자르고 여유를 둬라.**
129
+ - **자가 무효화**: auto-memory 는 Claude 가 쓰고 **세션 중에도 다시 쓴다.** `MEMORY.md` 정리가 같은
130
+ 세션이나 다음 세션에 **조용히 재팽창·되돌려질 수 있다.** 1회성 이벤트로 취급하지 마라. 정리 결과가
131
+ 유지되길 원하면 auto-memory 비활성 스위치가 존재한다는 사실을 사용자에게 알리고, **결정은 사용자에게** 맡겨라.
132
+ - **CLAUDE.md 캡 날조**: 다시 적는다. CLAUDE.md 에 **문서화된 바이트 한도가 없다.** 캡 수치를 제시하는
133
+ 순간 그건 **날조**다. 200줄은 soft target 이지 강제가 아니다.
134
+ - **스코프 오류**: 25KB 를 auto-memory **디렉터리 합계**에 적용하면 **없는 위반을 만들어낸다.**
135
+ topic 파일은 시작 시 로드조차 되지 않는다.
136
+ - **토큰으로 판정**: 게이트는 바이트와 줄-OR-바이트다. 토큰 추정은 게이트와 **무관하다.**
137
+ - **Codex 문서의 오해 유발 프레이밍**: 공식문서가 전역 → 프로젝트 순서 리스트로 서술해 **전역 파일이
138
+ 32 KiB 예산을 쓰는 것처럼 읽힌다.** 전역은 이 예산과 무관하고 캡이 없다. **프로젝트 예산에서 빼지 마라.**
139
+ - **`@` 리터럴 오독**: 코드 스팬·펜스 안의 `@README` 는 import 가 아니다. import 로 착각해 손대지 마라.
140
+
141
+ ## 원칙
142
+ - **날조 금지.** 문서화된 한도가 없으면 "없다"고 말한다. 없는 수치를 만들지 않는다.
143
+ - **재기 전에 자르지 않는다.** 인벤토리 없는 압축은 추측이다.
144
+ - **무손실 우선.** 지우기 전에 옮긴다. 지우는 건 **무효화된 옛 값**뿐이다.
145
+ - **바이트로 말한다.** 토큰으로 말하지 않는다.
146
+ - **런타임을 섞지 않는다.** Claude 규칙을 Codex 에 적용하지 않는다. 반대도 같다.
147
+ - **겹치면 양보한다.** `/doctor` 가 이미 하는 일은 `/doctor` 에 맡긴다.
148
+ - **수치엔 확인 시점을 붙인다.** 버전이 바뀌면 사실도 바뀐다.
149
+
150
+ ARGUMENTS: [--dry-run] [--claude|--codex] [대상 파일/경로] (없으면 현재 프로젝트·전역의 Claude·Codex 메모리 파일 전체를 인벤토리)
@@ -0,0 +1,266 @@
1
+ ---
2
+ name: interval-report
3
+ description: "(banker) 장기 수행의 중간 보고를 docs/intermission.md 로 만들고 계획된 작업이 끝날 때까지 갱신. 시작 시각은 date 로 실측해 파일에 영속하고, ETA 는 단일 숫자 대신 범위+확신 라벨로 낸다. 'interval-report'/'중간 보고'/'진행 상황 보고'/'intermission' 시 사용."
4
+ ---
5
+
6
+ # interval-report: 장기 수행 중간 보고 (docs/intermission.md)
7
+
8
+ 장기 수행은 사람에게 보이지 않는다. 사용자는 지시를 넣고 나면 지금 어디쯤인지, 언제 끝나는지, 그동안 무슨 일이 있었는지 알 방법이 없다.
9
+ 이 스킬은 그 공백을 `docs/intermission.md` 파일 하나로 메우고, **계획된 작업이 끝날 때까지 그 파일을 갱신한다.**
10
+ 읽는 사람이 전체 trajectory 를 한 번에 파악할 수 있어야 한다. 그게 이 파일의 유일한 존재 이유다.
11
+
12
+ 여기서 오작동의 대가는 느린 진행이 아니라 **거짓 보고**다. 시각을 추측하면 elapsed 가 허구가 되고, 자신감 있는 단일 숫자 ETA 를 뱉으면 사용자가 그걸 믿고 계획을 세운다.
13
+ 그래서 아래의 실측 규칙과 ETA 정직성 규칙은 보고의 매끄러움보다 우선한다. 답변은 한글(기술 토큰·경로·명령은 영문).
14
+
15
+ **런타임:** 외부 도구·프레임워크 의존이 없다. 필요한 것은 `date` 와 파일 쓰기뿐이라 Claude Code(OMC)·Codex CLI(OMX) 양쪽에서 동일하게 동작한다.
16
+
17
+ - **시각의 출처는 `date` 하나다.** 두 런타임 모두 컨텍스트에 시:분 시각이 없다. 이건 직접 관측된 사실이고, 매번 셸에서 실측하는 **유일한 근거**다.
18
+ - **ultragoal 이 있으면 읽고, 없어도 동작한다**(아래 "ultragoal 관계").
19
+ - **자가 트리거는 설치하지 않는다.** 이 스킬은 호출되면 동작한다(아래 "When NOT to use").
20
+
21
+ ## When to use
22
+ - 사용자 지시 하나가 여러 단계·긴 시간으로 늘어나, 중간에 사람이 상태를 볼 수 없는 수행.
23
+ - 자리를 비운 사용자가 돌아와 그동안의 trajectory 를 한 번에 파악해야 할 때.
24
+ - 진행 중 사용자가 알아야 할 일이 생겼는데(가정이 깨짐, 외부 대기, 예상 밖 발견) 지금 당장 물을 만큼은 아닐 때.
25
+ - 사용자가 `interval-report`/`중간 보고`/`진행 상황 보고`/`intermission` 이라고 할 때.
26
+
27
+ ## When NOT to use
28
+ - **단발 작업.** 한 번에 끝나는 일에 보고 파일을 세우면 파일 관리가 작업보다 비싸다.
29
+ - **상태의 원본 저장소로.** 이 스킬은 렌더러지 원장이 아니다. 진행 상태의 원본이 필요하면 `ultragoal` 이다.
30
+ - **컨텍스트 임계 감지·자동 발화.** statusLine·hook 으로 스스로 발화하려 들지 마라. **그 영역은 `smart-compact` 소유다.** 트리거 메커니즘을 복제하지도, 설치하지도 않는다. interval-report 는 호출되면 동작하고, 갱신 시점은 아래 "3. 갱신 리듬" 이 정한다.
31
+ - **compaction 직전 준비.** 그건 `ready-compact` 다. 이름이 비슷해 헷갈리지만 하는 일이 다르다.
32
+
33
+ | | interval-report | ready-compact |
34
+ |---|---|---|
35
+ | 계기 | **연속**(작업이 끝날 때까지 갱신) | 이벤트 1회성(compaction 직전) |
36
+ | 독자 | **사람** | 다음 세션의 에이전트 |
37
+ | 산출물 | `docs/intermission.md`(자급식 보고서) | 붙여넣기용 resume 프롬프트 |
38
+ | 담는 것 | trajectory 전체(시작·경과·잔여·이벤트) | 휘발성 맥락(다음 한 수) |
39
+ | 시간 | **핵심**(실측·영속·ETA) | 범위 밖 |
40
+
41
+ 둘은 같은 세션에서 공존한다. 경쟁하지 않는다. 보고서가 있다고 resume 프롬프트를 생략하지 말고, 그 반대도 마찬가지다.
42
+
43
+ ## 측정 범위 (여기가 틀리면 나머지 숫자가 전부 틀린다)
44
+
45
+ 측정 대상은 세션 전체가 아니라 **마지막 사용자 지시로 시작된 현재 수행분**이다.
46
+
47
+ > **시작 시각 = 마지막으로 사용자가 대화·지시한 시점.**
48
+
49
+ - 세션은 며칠을 살아 있을 수 있고 그중 대부분은 사용자가 자리에 없던 시간이다. 세션 시작을 기준으로 잡으면 elapsed 는 "이 지시가 얼마나 걸리고 있나" 가 아니라 "이 터미널이 얼마나 오래 열려 있나" 를 재게 된다. 후자는 아무도 궁금해하지 않는다.
50
+ - 사용자가 **새 지시**를 넣으면 그것이 새 수행분이다. 시작 시각을 새로 찍고 보고서를 새로 연다.
51
+ - 사용자의 개입이 지시가 아니라 **승인·답변**(예: "응", "그렇게 해", "1번으로")이면 수행분은 이어진다. 시작 시각을 옮기지 마라.
52
+ - 애매하면 **옮기지 않는 쪽**을 택한다. 두 실수의 대가가 대칭이 아니다. 옮기는 실수는 elapsed 를 낙관 쪽으로 붕괴시키고, 안 옮기는 실수는 비관 쪽으로 어긋난다. 보고서에서는 낙관 편향이 더 나쁘다.
53
+
54
+ ## 시간 메커닉
55
+
56
+ ### 실측
57
+ ```bash
58
+ date +%s # epoch 초. 산술은 이 값으로만.
59
+ date '+%Y-%m-%d %H:%M %Z' # 사람이 읽는 표기. 보고서에 그대로 싣는다.
60
+ ```
61
+
62
+ 시각을 추측하거나 대화 내용에서 역산하지 마라. 두 런타임 모두 컨텍스트에 시:분 시각이 없다.
63
+ 이 문장이 `date` 를 부르는 근거의 전부다. 다른 근거를 덧붙이지 마라.
64
+
65
+ ### READ-BACK 불변 규칙 (이 스킬의 핵심 안전장치)
66
+
67
+ > **파일에 이미 시작 시각이 있으면 절대 덮어쓰지 않는다.**
68
+
69
+ 갱신할 때는 언제나 파일을 먼저 읽는다. 계산은 그다음이다.
70
+
71
+ ```bash
72
+ F=docs/intermission.md
73
+ if [ -f "$F" ] && grep -q '^started_epoch:' "$F"; then
74
+ START=$(grep -m1 '^started_epoch:' "$F" | tr -cd '0-9') # 파일이 정본
75
+ else
76
+ START=$(date +%s) # 최초 1회만
77
+ fi
78
+ NOW=$(date +%s)
79
+ ELAPSED=$(( NOW - START ))
80
+ printf 'start=%s elapsed=%dh %02dm\n' "$START" $(( ELAPSED / 3600 )) $(( ELAPSED % 3600 / 60 ))
81
+ ```
82
+
83
+ - **왜 영속이 필수인가:** compaction·resume 후에는 모델이 시작 시각을 기억하지 못한다. 그때 `now` 로 재스탬프하면 elapsed 가 0 으로 붕괴한다. 붕괴는 조용하고, 하필 **긴 작업일수록 잘 일어난다**(길수록 compaction 을 겪으니까). 즉 리포트가 가장 필요한 순간에 리포트가 가장 낙관적으로 거짓말한다. 이 규칙은 편의보다 우선한다.
84
+ - **정수 산술만 쓴다.** `date -d @...`(GNU)와 `date -v`(BSD)는 문법이 갈린다. `date +%s` 로 epoch 만 얻고 뺄셈은 셸에 맡기면 분기가 사라진다.
85
+ - **사람이 읽는 표기도 같이 영속한다.** epoch 만 두면 파일을 연 사람이 값을 검증할 수 없다.
86
+
87
+ ## ETA 정직성
88
+
89
+ ETA 는 **실측량에서만** 유도한다: 경과 시간, 완료 수, 진행중 수, 대기 수. 이 넷 말고 다른 입력을 지어내지 마라.
90
+
91
+ **규칙 1. 단일 숫자 금지. 범위 + 확신 라벨.**
92
+ - 나쁨: `예상 종료: 17:30`
93
+ - 좋음: `예상 잔여: 40m ~ 2h (확신: 낮음)` / `예상 종료: 17:00 ~ 18:20 KST`
94
+ - 확신 라벨은 3단이면 충분하다: 높음 / 보통 / 낮음. 소수점 확신도가 필요하면 그건 `curation` 의 형식이지 여기가 아니다.
95
+
96
+ **규칙 2. 가정을 인라인에 적는다.**
97
+ ETA 바로 옆이나 바로 아래에 무엇을 가정했는지 쓴다. 별도 문서로 미루지 마라. 읽는 사람이 ETA 를 보는 **그 자리에서** 가정을 봐야 정정할 수 있다.
98
+
99
+ > 예상 잔여: 40m ~ 2h (확신: 낮음)
100
+ > 가정: 남은 3건이 끝난 2건과 비슷한 크기다(확인된 바 없음). 5번이 사용자 승인 대기라 상한이 열려 있다.
101
+
102
+ **규칙 3. 90% 천장을 의식한다.**
103
+ 카운트가 9/10 을 가리킬 때가 **남은 노력이 가장 클 수 있는 지점**이다. 마지막 항목은 대개 통합·검증·사용자 확인이고, 그것들은 앞의 9개와 크기가 다르다.
104
+ 선형 외삽(경과 ÷ 완료 × 대기)은 초반에 그럭저럭 맞고 **꼬리에서 무너진다.** 꼬리에서 성립하는 척하지 마라.
105
+ - 카운트가 올라갈수록 범위의 **상한을 좁히지 마라.** 좁히고 싶은 충동이 정확히 그 편향이다.
106
+ - 남은 항목의 성격이 앞의 항목과 다르면(검증·리뷰·사용자 결정 대기) 그 사실을 가정에 적고 확신을 낮춘다.
107
+ - 진행률 퍼센트 하나로 요약하지 마라. 작업 표의 카운트가 이미 그 정보를 편향 없이 담고 있다.
108
+
109
+ **규칙 4. 자기모순 금지.**
110
+ "정직한 ETA" 를 표방하면서 자신감 있는 단일 숫자를 뱉으면 자기모순이다. 그건 ETA 를 아예 안 내는 것보다 **나쁘다.** 사용자가 정직성 표방을 믿고 그 숫자를 더 신뢰하기 때문이다.
111
+ 범위를 못 내겠으면 **"모른다" 고 적어라.** 그건 허용된 답이다. 근거 없는 숫자를 채워 넣는 것만 금지다.
112
+
113
+ ## ultragoal 관계 (렌더러지 원장이 아니다)
114
+
115
+ `ultragoal` 은 목표 목록·상태·타임스탬프를 append-only 원장으로 **양 런타임에 이미 영속화**한다. 이 스킬은 그것을 복제하지 않는다.
116
+
117
+ - **있으면 읽어서 렌더한다.** 작업 표의 순서·작업·상태를 원장에서 채우고, 보고서에 원장 경로를 출처로 적는다.
118
+ - Claude(OMC): `.omc/ultragoal/`
119
+ - Codex(OMX): `.omx/ultragoal/`
120
+ - **없어도 동작한다.** ultragoal 은 opt-in 이라 대부분의 세션에 없다. 없으면 현재 지시의 작업 목록에서 표를 직접 만든다. **ultragoal 을 요구하지도, 대신 켜지도 마라.**
121
+ - **상태를 복제하지 않는다.** 보고서는 원장의 파생물이다. 둘이 어긋나면 원장이 맞다. 보고서를 고쳐 원장을 반영하지, 원장을 보고서에 맞추지 않는다.
122
+ - **왜 그 위에 얹는가:** ultragoal 에는 시간·ETA 개념이 없고 산출물이 기계 포맷이다. 이 스킬이 더하는 것은 딱 두 가지다. 얇은 시간 레이어(실측·영속·경과·ETA), 그리고 사람용 렌더러. 그 둘을 넘어가면 ultragoal 을 다시 구현하는 것이다.
123
+
124
+ ## 워크플로
125
+
126
+ ### 0. READ-BACK (추정 금지)
127
+ 언제나 여기서 시작한다. 파일이 있는지, 시작 시각이 무엇인지 **읽어서** 확인한다. 기억에 의존하지 마라.
128
+ 위 "READ-BACK 불변 규칙" 의 블록을 그대로 돌려 `START`·`ELAPSED` 를 얻는다. 여기서 읽은 `started_epoch` 는 4단계 검증의 기준값이다.
129
+
130
+ 파일이 없으면 최초 실행이다. 1단계로 간다. 있으면 **갱신**이다. 3단계로 간다.
131
+
132
+ ### 1. 자리 잡기 (docs/ + .gitignore, 최초 1회)
133
+ 산출물은 타깃 repo 의 `docs/intermission.md` 다. `docs/` 가 없으면 만든다.
134
+
135
+ 이건 **세션 로컬 작업물**이지 그 프로젝트의 문서가 아니다. 커밋되면 우리 세션의 진행 상황이 남의 repo 히스토리에 영구히 남는다. 그래서 `.gitignore` 에 기본 항목을 추가한다.
136
+
137
+ ```
138
+ # interval-report: session-local progress report (not project documentation)
139
+ docs/intermission.md
140
+ ```
141
+
142
+ - **`.gitignore` 는 그 프로젝트의 파일이지 우리가 만든 게 아니다.** 그러므로 **사용자에게 알리고 진행한다.** 무엇을 왜 추가하는지 한 줄로 말하면 된다. 승인을 기다리며 멈추라는 게 아니라, 사용자가 모르는 채로 남의 repo 가 바뀌는 일을 막으라는 것이다.
143
+ - **멱등하게.** 이미 그 항목이 있으면 추가하지 않는다. 이미 무시되고 있어도(상위 규칙, `docs/` 통째 무시 등) 추가하지 않는다. 확인은 이걸로 한다:
144
+ ```bash
145
+ git check-ignore -q docs/intermission.md && echo "이미 무시됨: 추가 불필요"
146
+ ```
147
+ - git repo 가 아니면(`git rev-parse --git-dir` 실패) 이 단계를 통째로 건너뛴다. 에러가 아니다.
148
+ - 사용자가 보고서를 커밋 대상으로 원한다고 명시하면 그건 사용자의 repo 다. 추가하지 말고 그대로 둔다.
149
+
150
+ ### 2. 보고서 렌더
151
+ 필수 항목 8개는 **전부** 있어야 한다: 시작 시간 / 현재 상태 / elapsed / 예상 잔여 / 예상 종료 / 진행·잔여 작업 표 / 발생 이벤트 / 인지 중인 constraints.
152
+
153
+ **작업 표는 하나다.** 완료분과 잔여분을 따로 두지 마라. 하나의 표에 순서대로 놓아야 trajectory 가 한눈에 들어온다. 상태 값은 `완료`·`진행중`·`대기` 3종뿐이다.
154
+
155
+ ```markdown
156
+ ---
157
+ started_epoch: 1784181572
158
+ started_human: "2026-07-16 14:59 KST"
159
+ updated_human: "2026-07-16 16:20 KST"
160
+ ---
161
+
162
+ # 중간 보고: DB 마이그레이션 롤아웃
163
+
164
+ | 항목 | 값 |
165
+ |---|---|
166
+ | 시작 | 2026-07-16 14:59 KST |
167
+ | 현재 상태 | 3번(스테이징 검증) 진행 중. 4번부터 대기. |
168
+ | elapsed | 1h 21m |
169
+ | 예상 잔여 | 40m ~ 2h (확신: 낮음) |
170
+ | 예상 종료 | 17:00 ~ 18:20 KST |
171
+
172
+ **ETA 가정:** 남은 3건이 끝난 2건과 비슷한 크기다(확인된 바 없음). 5번이 사용자 승인 대기라 상한이 열려 있다.
173
+
174
+ ## 작업
175
+
176
+ | # | 작업 | 상태 |
177
+ |---|---|---|
178
+ | 1 | 스키마 diff 추출 | 완료 |
179
+ | 2 | 마이그레이션 스크립트 작성 | 완료 |
180
+ | 3 | 스테이징 검증 | 진행중 |
181
+ | 4 | 롤백 절차 문서화 | 대기 |
182
+ | 5 | 운영 반영 | 대기 |
183
+
184
+ ## 발생 이벤트
185
+ - 15:34 스테이징 시드가 3개월 낡아 일부 검증을 건너뜀. 사용자 판단이 필요할 수 있음.
186
+ - 16:02 `npm i` 가 프록시 뒤에서 2회 실패. 재시도로 통과. 조치 불필요.
187
+
188
+ ## 인지 중인 constraints
189
+ - 운영 반영은 사용자 승인 후에만(전역 규칙).
190
+ - 스테이징 DB 는 18:00 에 야간 배치가 잡아간다. 3번을 그 전에 끝내야 한다.
191
+ - 롤백 절차는 아직 검증되지 않았다. 5번의 전제 조건이다.
192
+ ```
193
+
194
+ - **발생 이벤트**는 사용자가 알아야 할 것만 적는다. 로그가 아니다. 기준은 "이걸 몰랐다면 사용자가 다르게 판단했을까" 다. 아니면 빼라. 다만 **가정이 깨진 사건은 반드시 남긴다.**
195
+ - **constraints** 는 지금 인지하고 있는 제약이다. 환경·순서 의존·승인 게이트·외부 대기. 사용자가 풀어줄 수 있는 것이 여기 있으면 그게 이 절의 값어치다.
196
+ - 항목에 쓸 내용이 없으면 항목을 **지우지 말고** "없음" 이라고 적는다. 없는 항목과 빈 항목은 다르다.
197
+
198
+ ### 3. 갱신 리듬
199
+ 갱신은 **계획된 작업이 끝날 때까지** 이어진다. 시점은 사건이 정한다:
200
+
201
+ - 작업 표의 항목 상태가 바뀌었을 때(완료·진행중 전환).
202
+ - 사용자가 알아야 할 이벤트가 생겼을 때.
203
+ - constraints 가 바뀌었을 때(제약이 생기거나 풀렸을 때).
204
+ - ETA 의 가정이 깨졌을 때. **이때가 가장 중요하다.** 가정이 깨졌는데 ETA 를 그대로 두면 그 순간부터 보고서는 거짓이다.
205
+ - 사용자가 물었을 때.
206
+
207
+ 매 갱신마다 0단계 READ-BACK 을 먼저 한다. `updated_human` 을 새로 찍고 `started_epoch` 는 손대지 않는다.
208
+ 갱신할 게 없으면 갱신하지 않는다. 같은 내용으로 타임스탬프만 바꾸는 것은 신호가 아니라 잡음이다.
209
+
210
+ ### 4. 검증 (보고 의무)
211
+ **보고서를 썼다는 사실로 성공을 선언하지 마라.** 파일은 언제나 써진다. 붕괴한 시작 시각도, 자신감 있는 단일 숫자도 똑같이 잘 써진다.
212
+ 판정은 **갱신할 때마다** 아래를 실제로 돌려서 한다.
213
+
214
+ ```bash
215
+ F=docs/intermission.md
216
+ grep -m1 '^started_epoch:' "$F" # 0단계에서 읽은 값과 동일해야 한다
217
+ grep -m1 '^started_human:' "$F"
218
+ git check-ignore -q "$F" 2>/dev/null && echo "gitignore: ok" || echo "gitignore: 미적용 (git repo 가 아니면 정상, 아니면 1단계 확인)"
219
+ ```
220
+
221
+ 체크리스트. 하나라도 아니오면 고치고 다시 본다.
222
+ - `started_epoch` 가 0단계에서 읽은 값과 **같은가.** 다르면 재스탬프 사고이고 elapsed 는 거짓이다. 즉시 원래 값으로 되돌린다.
223
+ - elapsed 가 **직전 보고보다 커졌는가.** 줄었으면 같은 사고다.
224
+ - 필수 항목 8개가 **전부 있는가.** "없음" 도 값이다. 항목 자체를 지우지 않는다.
225
+ - 작업 표가 **하나인가.** 상태 값이 완료·진행중·대기 3종뿐인가.
226
+ - ETA 가 **범위 + 확신 라벨**인가. 단일 시각 하나면 규칙 위반이다.
227
+ - ETA 옆에 **가정이 적혀 있는가.** 가정이 지금도 유효한가.
228
+ - 표의 상태가 실제 진행과 맞는가. **갱신하지 않은 보고서는 오래된 보고서가 아니라 틀린 보고서다.**
229
+
230
+ 사용자에게는 파일 경로와 함께 **지금 값**을 한 줄로 준다. 파일을 열게 하지 마라.
231
+
232
+ ```
233
+ docs/intermission.md 갱신: elapsed 1h 21m, 2/5 완료, 예상 잔여 40m ~ 2h (확신: 낮음)
234
+ ```
235
+
236
+ ## 함정
237
+ - **now 로 재스탬프하는 것.** 이 스킬에서 데이터가 거짓이 되는 유일하고 실재하는 경로다. 파일에 시작 시각이 있으면 그게 정본이다.
238
+ - **세션 시작을 시작 시각으로 잡는 것.** 측정 대상은 마지막 사용자 지시로 시작된 수행분이다.
239
+ - **승인 한마디를 새 지시로 오인해 시작 시각을 옮기는 것.** 애매하면 옮기지 않는다.
240
+ - **자신감 있는 단일 숫자.** "정직한 ETA" 를 표방하면서 이걸 하면 자기모순이고, 침묵보다 나쁘다.
241
+ - **꼬리에서 선형 외삽을 믿는 것.** 9/10 이 남은 노력이 가장 큰 지점일 수 있다.
242
+ - **표를 둘로 쪼개는 것.** 완료 표와 잔여 표를 나누면 trajectory 가 끊긴다. 표는 하나다.
243
+ - **이벤트 절을 로그로 만드는 것.** 전부 적으면 아무것도 안 적은 것과 같다. 기준은 "사용자의 판단이 달라졌을까" 다.
244
+ - **파일만 쓰고 끝내는 것.** 파일은 언제나 써진다. 검증은 4단계 체크리스트다.
245
+ - **`.gitignore` 를 정리하려 드는 것.** 여기서 하는 일은 한 줄 멱등 추가지 정리가 아니다(정리는 `refresh-git-ignore` 소관이고 이 스킬이 부를 일이 아니다).
246
+ - **남의 repo 를 조용히 건드리는 것.** `.gitignore` 변경은 알리고 진행한다.
247
+ - **`date` 의 계산 옵션에 의존하는 것.** GNU 와 BSD 가 갈린다. epoch 뺄셈만 쓴다.
248
+ - **ultragoal 상태를 보고서에 복제하는 것.** 어긋나면 원장이 맞다.
249
+ - **자가 트리거를 설치하는 것.** `smart-compact` 영역이다.
250
+ - **보고서를 resume 프롬프트로 쓰는 것.** 그건 `ready-compact` 다. 독자가 다르다(사람 대 에이전트).
251
+
252
+ ## 원칙
253
+ - 시각은 `date` 로 실측한다. 추측·역산 금지.
254
+ - 시작 시각은 파일이 정본이다. READ-BACK 이 먼저, 계산은 그다음.
255
+ - 측정 단위는 세션이 아니라 마지막 사용자 지시로 시작된 수행분이다.
256
+ - ETA 는 실측량에서만 유도하고, 범위 + 확신 라벨로 내고, 가정을 곁에 적는다.
257
+ - 모르면 모른다고 적는다. 그게 허용된 답이고 자신 있는 오답보다 낫다.
258
+ - 표는 하나다. 전체 trajectory 가 한눈에 들어와야 한다.
259
+ - 이 스킬은 시간 레이어와 렌더러다. 원장도, 트리거도, resume 프롬프트도 아니다.
260
+ - 산출물은 세션 로컬이다. 남의 repo 에 남기지 않는다.
261
+ - 계획된 작업이 끝날 때까지 갱신한다. 끝나면 마지막 갱신으로 닫는다.
262
+
263
+ ARGUMENTS: [--path <파일>] [--close] [지시 요약] (없으면 `docs/intermission.md` 에 현재 수행분을 렌더하고 계획된 작업이 끝날 때까지 갱신)
264
+ - `--path <파일>`: 산출 경로를 바꾼다. `.gitignore` 게이트는 그 경로에 그대로 적용한다.
265
+ - `--close`: 마지막 갱신을 하고 보고서를 닫는다. 전 항목을 종료 상태로 맞추고, elapsed 를 확정하고, 예상 잔여·예상 종료를 실제 값으로 대체한다.
266
+ - 인자 없이 파일이 이미 있으면 그건 **갱신**이다. 새로 만들지 마라. 언제나 READ-BACK 이 먼저다.