leerness 1.9.221 β†’ 1.9.222

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/CHANGELOG.md CHANGED
@@ -1,5 +1,40 @@
1
1
  # Changelog
2
2
 
3
+ ## 1.9.222 β€” 2026-05-22
4
+
5
+ **πŸ›‘ session-resume --auto-fix μ•ˆμ „ 회볡 + handoff λ³Έλ¬Έ 비정상 μ’…λ£Œ μžλ™ λ…ΈμΆœ.**
6
+
7
+ ### 1. `leerness session-resume --auto-fix` β€” μ•ˆμ „ν•œ μžλ™ 회볡
8
+ - 1.9.220 detect / 1.9.221 MCP / 1.9.222 **auto-fix**
9
+ - `wakeup-missed` μ‹ ν˜Έ 감지 μ‹œ β†’ 30λΆ„+ μ§€λ‚œ pending wakeup μžλ™ `superseded`
10
+ - `state.supersededReason: 'auto-fix-1.9.222-abnormal-shutdown'`
11
+ - μ‚¬μš©μž/AIκ°€ μˆ˜λ™ 정리할 ν•„μš” 없이 λ‹€μŒ wakeup이 정상 λ™μž‘
12
+ - `--auto-fix` μ˜΅μ…˜μ΄ μ—†μœΌλ©΄ κΈ°μ‘΄ λ™μž‘ κ·ΈλŒ€λ‘œ (κ°μ§€λ§Œ, λ³€κ²½ X)
13
+
14
+ ### 2. handoff λ³Έλ¬Έ μžλ™ λ…ΈμΆœ β€” 비정상 μ’…λ£Œ μ„Ήμ…˜
15
+ - 1.9.220 ν—€λ“œλΌμΈ (`πŸ”Œ λΉ„μ •μƒμ’…λ£Œ <severity>`) + 1.9.222 **λ³Έλ¬Έ**
16
+ - `severity: high` β†’ `## 🚨 비정상 μ’…λ£Œ 감지 (1.9.220, severity: high)` λ³Έλ¬Έ μ„Ήμ…˜ μžλ™
17
+ - `severity: medium` β†’ `## ⚠ 비정상 μ’…λ£Œ 감지` λ³Έλ¬Έ μ„Ήμ…˜ μžλ™
18
+ - λ³Έλ¬Έ 좜λ ₯ μœ„μΉ˜: pre-wake-audit μ„Ήμ…˜ λ‹€μŒ, ν™œμ„± λ£° 이전
19
+ - top 3 μ‹ ν˜Έ + 재개 κ°€μ΄λ“œ + auto-fix κ°€μ΄λ“œ ν•œ λ²ˆμ— λ…ΈμΆœ
20
+
21
+ ### 3. CLAUDE.md / AGENTS.md 1.9.214~221 운영 κ°•ν™” 8 λΌμš΄λ“œ 톡합
22
+ - drift 차단을 μœ„ν•œ `## 운영 κ°•ν™” 8 λΌμš΄λ“œ (1.9.214~221)` μ„Ήμ…˜ λˆ„μ 
23
+ - 9 λΌμš΄λ“œ (drift 차단 / handoff ν—€λ“œλΌμΈ / MCP 5μ’… / session close / handoff JSON 4 톡합 / 80 λΌμš΄λ“œ / 비정상 μ’…λ£Œ / MCP 60 / auto-fix) λͺ¨λ‘ 단일 μ‹œμ•Ό λ…ΈμΆœ
24
+
25
+ ### 4. λˆ„μ  νšŒκ·€ (1.9.207~221) β€” λͺ¨λ‘ μœ μ§€
26
+
27
+ ### 5. stress-v167 β€” 14/14 PASS
28
+ - 1.9.222 (6): VERSION + auto-fix (격리) + auto-fix λ―Έμ§€μ • μ‹œ λ™μž‘ + handoff λ³Έλ¬Έ λ…ΈμΆœ + handoff 정상 μ‹œ λ―Έλ…ΈμΆœ + CLAUDE 8 λΌμš΄λ“œ μ„Ήμ…˜
29
+ - μ„±λŠ₯ (2): cold_start avg 408ms / MCP 60 도ꡬ 413ms
30
+ - λˆ„μ  νšŒκ·€ (6): 1.9.207~221
31
+
32
+ ### 6. μžλ™ release (84 λΌμš΄λ“œ main-push streak Β· 45 λΌμš΄λ“œ npm publish streak)
33
+
34
+ πŸ›‘ **비정상 μ’…λ£Œ μ‹œμŠ€ν…œ μ™„μ„±**: 1.9.220 detect β†’ 1.9.221 MCP β†’ 1.9.222 **auto-fix** + **λ³Έλ¬Έ μžλ™ λ…ΈμΆœ** (3 λΌμš΄λ“œ λˆ„μ )
35
+
36
+ ---
37
+
3
38
  ## 1.9.221 β€” 2026-05-22
4
39
 
5
40
  **πŸŽ‰ MCP 60 도ꡬ λ§ˆμΌμŠ€ν†€ + abnormalShutdown JSON 톡합 (handoff/session close).**
package/README.md CHANGED
@@ -2,7 +2,7 @@
2
2
 
3
3
  > **AI μ½”λ”© μ—μ΄μ „νŠΈμ˜ κ±°μ§“ μ™„λ£ŒΒ·μ€‘λ³΅Β·λ§κ°Β·μΆ©λŒμ„ λ§‰μ•„μ£ΌλŠ” κ²€μˆ˜Β·κΈ°μ–΅Β·ν˜‘μ—… CLI ν•˜λ„€μŠ€.**
4
4
 
5
- [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.221-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v166-16%2F16-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-60_πŸŽ‰-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-151-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-83_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![mcp-60](https://img.shields.io/badge/πŸŽ‰_MCP-60_도ꡬ_λ§ˆμΌμŠ€ν†€-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-374ms-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
5
+ [![npm](https://img.shields.io/badge/npm-leerness-blue)](https://www.npmjs.com/package/leerness) [![version](https://img.shields.io/badge/version-1.9.222-green)]() [![tests](https://img.shields.io/badge/e2e-217%2F217-success)]() [![stress](https://img.shields.io/badge/stress--v167-14%2F14-success)]() [![mcp](https://img.shields.io/badge/MCP--tools-60_πŸŽ‰-brightgreen)]() [![rounds](https://img.shields.io/badge/autonomous--rounds-152-blueviolet)]() [![main-push](https://img.shields.io/badge/release--main--push-84_rounds-success)]() [![goal-matrix](https://img.shields.io/badge/λͺ©μ _맀트릭슀-100%2F100_(5μΆ•)-brightgreen)]() [![auto-fix](https://img.shields.io/badge/πŸ›‘_session--resume-auto--fix-blueviolet)]() [![perf](https://img.shields.io/badge/cold_start-408ms-success)]() [![install](https://img.shields.io/badge/npm_i_leerness-μ¦‰μ‹œ_μ‚¬μš©_κ°€λŠ₯-success)]() [![sandbox](https://img.shields.io/badge/runCommandSafe-cwd_jail%2Benv_scrub-success)]() [![license](https://img.shields.io/badge/license-MIT-lightgrey)]()
6
6
 
7
7
  ```
8
8
  ╔══════════════════════════════════════════════════════════════╗
@@ -12,9 +12,9 @@
12
12
  β•‘ β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β• β–ˆβ–ˆβ•”β•β•β–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β•šβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•”β•β•β• β•šβ•β•β•β•β–ˆβ–ˆβ•‘ β•‘
13
13
  β•‘ β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ•‘ β–ˆβ–ˆβ•‘β–ˆβ–ˆβ•‘ β•šβ–ˆβ–ˆβ–ˆβ–ˆβ•‘β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•—β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ•‘ β•‘
14
14
  β•‘ β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β• β•šβ•β•β•šβ•β• β•šβ•β•β•β•β•šβ•β•β•β•β•β•β•β•šβ•β•β•β•β•β•β• β•‘
15
- β•‘ v1.9.221 AI Agent Reliability Harness + Sandbox β•‘
15
+ β•‘ v1.9.222 AI Agent Reliability Harness + Sandbox β•‘
16
16
  β•‘ verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β•‘
17
- β•‘ πŸŽ‰ MCP 60 도ꡬ λ§ˆμΌμŠ€ν†€ Β· handoff JSON 4 톡합 ν•„λ“œ μ™„μ„± β•‘
17
+ β•‘ πŸ›‘ session-resume --auto-fix Β· handoff λ³Έλ¬Έ 비정상 μ’…λ£Œ μžλ™ β•‘
18
18
  β•šβ•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•β•
19
19
  ```
20
20
 
package/bin/harness.js CHANGED
@@ -7,7 +7,7 @@ const cp = require('child_process');
7
7
  const os = require('os'); // 1.9.178: _publishToNpm μ—μ„œ os.tmpdir() μ‚¬μš© (μ „μ—­ import)
8
8
  const readline = require('readline');
9
9
 
10
- const VERSION = '1.9.221';
10
+ const VERSION = '1.9.222';
11
11
 
12
12
  // 1.9.184: DEP0190 (child_process shell: true) deprecation warning μ–΅μ œ (μ‚¬μš©μž λͺ…μ‹œ).
13
13
  // leerness λŠ” cross-platform PATH resolution 을 μœ„ν•΄ shell: true λ₯Ό μ˜λ„μ μœΌλ‘œ μ‚¬μš© (claude.cmd / ollama.cmd λ“± Windows .cmd 처리).
@@ -3055,6 +3055,7 @@ function requestsCmd(root, sub, ...rest) {
3055
3055
  }
3056
3056
 
3057
3057
  // 1.9.220: leerness session-resume β€” 비정상 μ’…λ£Œ 감지 + 자율 재개 κ°€μ΄λ“œ (μ‚¬μš©μž λͺ…μ‹œ)
3058
+ // 1.9.222: --auto-fix μ˜΅μ…˜ μΆ”κ°€ β€” μ•ˆμ „ν•œ μžλ™ 회볡 (wakeup supersede)
3058
3059
  function sessionResumeCmd(root) {
3059
3060
  root = absRoot(root);
3060
3061
  const isTty = process.stdout && process.stdout.isTTY;
@@ -3065,6 +3066,45 @@ function sessionResumeCmd(root) {
3065
3066
  const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
3066
3067
 
3067
3068
  const result = _detectAbnormalShutdown(root);
3069
+
3070
+ // 1.9.222: --auto-fix β€” μ•ˆμ „ν•œ μ‹ ν˜Έλ³„ μžλ™ 회볡
3071
+ const autoFix = has('--auto-fix');
3072
+ if (autoFix && result.abnormalShutdown) {
3073
+ result.autoFixed = [];
3074
+ // 1) wakeup-missed β†’ 였래된 pending wakeup supersede (μ•ˆμ „: λ‹¨μˆœ μƒνƒœ λ³€κ²½)
3075
+ if (result.signals.some(s => s.kind === 'wakeup-missed')) {
3076
+ try {
3077
+ const state = _loadActiveWakeups(root);
3078
+ let fixed = 0;
3079
+ state.wakeups = state.wakeups.map(w => {
3080
+ if (w.status === 'pending') {
3081
+ const expectedMs = new Date(w.expectedFireAt).getTime();
3082
+ const deltaMin = Math.floor((Date.now() - expectedMs) / 60000);
3083
+ if (deltaMin > 30) {
3084
+ w.status = 'superseded';
3085
+ w.supersededReason = 'auto-fix-1.9.222-abnormal-shutdown';
3086
+ w.supersededAt = new Date().toISOString();
3087
+ fixed++;
3088
+ }
3089
+ }
3090
+ return w;
3091
+ });
3092
+ if (fixed > 0) {
3093
+ _writeActiveWakeups(root, state.wakeups);
3094
+ result.autoFixed.push({ kind: 'wakeup-missed', action: 'superseded', count: fixed });
3095
+ }
3096
+ } catch {}
3097
+ }
3098
+ // 2) auto-resume-plan-unused β†’ 60min+ λ―Έμ‚¬μš©μ€ μ•ˆλ‚΄λ§Œ (μžλ™ μ‚­μ œ X, μ‚¬μš©μžκ°€ κ²€ν† ν•΄μ•Ό 함)
3099
+ if (result.signals.some(s => s.kind === 'auto-resume-plan-unused')) {
3100
+ result.autoFixed.push({ kind: 'auto-resume-plan-unused', action: 'guidance-only', detail: 'leerness resume 으둜 적용 κ²€ν† ' });
3101
+ }
3102
+ // 3) in-progress-stale β†’ drop 결정은 μ‚¬μš©μž μ˜μ—­ (μžλ™ X)
3103
+ if (result.signals.some(s => s.kind === 'in-progress-stale')) {
3104
+ result.autoFixed.push({ kind: 'in-progress-stale', action: 'guidance-only', detail: 'leerness task list --status in-progress ν›„ μ‚¬μš©μž κ²°μ • ν•„μš”' });
3105
+ }
3106
+ }
3107
+
3068
3108
  if (has('--json')) { log(JSON.stringify(result, null, 2)); return; }
3069
3109
  log(cyan(`# leerness session-resume (1.9.220) β€” 비정상 μ’…λ£Œ 감지 + 자율 재개`));
3070
3110
  log(` detected at: ${result.detectedAt}`);
@@ -3093,6 +3133,18 @@ function sessionResumeCmd(root) {
3093
3133
  for (const g of result.resumeGuide) {
3094
3134
  log(` ${g}`);
3095
3135
  }
3136
+ // 1.9.222: --auto-fix κ²°κ³Ό λ…ΈμΆœ
3137
+ if (result.autoFixed && result.autoFixed.length > 0) {
3138
+ log('');
3139
+ log(grn(`## πŸ”§ auto-fix κ²°κ³Ό (${result.autoFixed.length})`));
3140
+ for (const af of result.autoFixed) {
3141
+ const icon = af.action === 'superseded' ? 'βœ“' : 'β„Ή';
3142
+ log(` ${icon} [${af.kind}] ${af.action}${af.count ? ` (count: ${af.count})` : ''}`);
3143
+ if (af.detail) log(dim(` ${af.detail}`));
3144
+ }
3145
+ } else if (autoFix) {
3146
+ log(dim(` (auto-fix 적용 λŒ€μƒ μ—†μŒ)`));
3147
+ }
3096
3148
  }
3097
3149
 
3098
3150
  // 1.9.208: leerness constraints <list|check|add> β€” ν”Œλž«νΌ/API μ œμ•½ 사전 체크 CLI (μ‚¬μš©μž λͺ…μ‹œ)
@@ -5956,6 +6008,30 @@ function handoff(root) {
5956
6008
  }
5957
6009
  }
5958
6010
  } catch {}
6011
+
6012
+ // 1.9.222: 비정상 μ’…λ£Œ 감지 λ³Έλ¬Έ μžλ™ λ…ΈμΆœ (handoff 직후 β€” κ°€μž₯ λ¨Όμ € 봐야 함)
6013
+ // high/medium severity μ‹œ μ¦‰μ‹œ λ…ΈμΆœ, low/none 은 λ¬΄μ‹œ
6014
+ try {
6015
+ const ad = _detectAbnormalShutdown(root);
6016
+ if (ad.abnormalShutdown && (ad.severity === 'high' || ad.severity === 'medium')) {
6017
+ const isTty = process.stdout && process.stdout.isTTY;
6018
+ const cy3 = s => isTty ? `\x1b[36m${s}\x1b[0m` : s;
6019
+ const rd3 = s => isTty ? `\x1b[31m${s}\x1b[0m` : s;
6020
+ const yl3 = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
6021
+ const dm3 = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
6022
+ log('');
6023
+ const sevIcon = ad.severity === 'high' ? '🚨' : '⚠';
6024
+ const sevColor = ad.severity === 'high' ? rd3 : yl3;
6025
+ log(sevColor(`## ${sevIcon} 비정상 μ’…λ£Œ 감지 (1.9.220, severity: ${ad.severity})`));
6026
+ ad.signals.slice(0, 3).forEach(s => {
6027
+ const ic = s.severity === 'high' ? '🚨' : (s.severity === 'medium' ? '⚠' : 'β„Ή');
6028
+ log(` ${ic} [${s.kind}] ${s.detail}`);
6029
+ });
6030
+ log(dm3(` β†’ 재개 κ°€μ΄λ“œ: leerness session-resume`));
6031
+ log(dm3(` β†’ μžλ™ 회볡: leerness session-resume --auto-fix (1.9.222)`));
6032
+ }
6033
+ } catch {}
6034
+
5959
6035
  // 1.9.8: active rules μžλ™ λ…ΈμΆœ (λ§€ μ„Έμ…˜ μ‹œμž‘ μ‹œ AIμ—κ²Œ λ³΄μž„)
5960
6036
  const activeRules = readRules(root).filter(r => r.status === 'active');
5961
6037
  if (activeRules.length) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.9.221",
3
+ "version": "1.9.222",
4
4
  "description": "Leerness: λΉ„νŒŒκ΄΄ λ§ˆμ΄κ·Έλ ˆμ΄μ…˜, μžλ™ 버전 κ°μ§€Β·μ—…λ°μ΄νŠΈ, κ³„νš/μ§„ν–‰/ν•Έλ“œμ˜€ν”„ μžλ™ν™”, κ²ŒμœΌλ¦„Β·μ‹œν¬λ¦ΏΒ·μΈμ½”λ”© μžλ™ κ°€λ“œ, Claude Code μŠ¬λž˜μ‹œ 톡합을 κ°–μΆ˜ ν•œκ΅­μ–΄ μš°μ„  AI 개발 ν•˜λ„€μŠ€.",
5
5
  "keywords": [
6
6
  "leerness",