leerness 1.9.198 β 1.9.200
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 +86 -0
- package/README.md +3 -3
- package/bin/harness.js +86 -16
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,91 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.9.200 β 2026-05-22
|
|
4
|
+
|
|
5
|
+
**π 200 λ§μΌμ€ν€ β 60 λΌμ΄λ μμ¨ λμ + 5μΆ λ§€νΈλ¦μ€ 96/100.**
|
|
6
|
+
|
|
7
|
+
### λμ μ±κ³Ό
|
|
8
|
+
- **62 λΌμ΄λ μ°μ** main μλ push (1.9.140~200)
|
|
9
|
+
- **23 λΌμ΄λ μ°μ** μλ npm publish (1.9.178~200)
|
|
10
|
+
- **8 λΌμ΄λ μ°μ** 5μΆ λ§€νΈλ¦μ€ λ³΄κ° (1.9.192~199): **88% β 96%**
|
|
11
|
+
- μ¬μ©μ λͺ
μ 7건 λͺ¨λ μ¦μ λμ
|
|
12
|
+
|
|
13
|
+
### 5μΆ λ§€νΈλ¦μ€ (1.9.191 β 1.9.200)
|
|
14
|
+
| μΆ | μμ | νμ¬ | Ξ |
|
|
15
|
+
|---|---|---|---|
|
|
16
|
+
| A. λ²μ© AI νλ€μ€ | 9.0 | **10.0** β | +1.0 |
|
|
17
|
+
| B. λ©ν° Sub-Agent μ€μΌμ€νΈλΌ | 8.5 | **9.5** | +1.0 |
|
|
18
|
+
| C. 곡μ νμ€ μ€ν¬ μλ νμ© | 8.0 | **9.0** | +1.0 |
|
|
19
|
+
| D. μ₯κΈ° λ§₯λ½ μ μ§ | 9.5 | **10.0** β | +0.5 |
|
|
20
|
+
| E. κ²μΌλ¦ λ°©μ§ | 9.0 | **9.5** | +0.5 |
|
|
21
|
+
| **μ’
ν©** | **44/50 (88%)** | **48/50 (96%)** | **+8%** |
|
|
22
|
+
|
|
23
|
+
### λ§μΌμ€ν€ λ³΄κ³ μ
|
|
24
|
+
- `_reports/milestone-1.9.200-60-rounds.md` (λΉκ³΅κ°)
|
|
25
|
+
- 60 λΌμ΄λ μ§μ²ν, ν΅μ¬ λ§μΌμ€ν€ 8건, μ¬μ©μ λͺ
μ λμ 7건, ν₯ν λ°©ν₯
|
|
26
|
+
|
|
27
|
+
### μ κ· κΈ°λ₯ (1.9.192~199) μμ½
|
|
28
|
+
1. **1.9.192**: 곡μ catalog μλ λ
ΈμΆ + 24h μΊμ (CμΆ μμ)
|
|
29
|
+
2. **1.9.193**: agents multi consensus β lessons.md μλ
|
|
30
|
+
3. **1.9.194**: handoff next-actions 7 ν΄λ¦¬μ€ν± + 24h+ lazy
|
|
31
|
+
4. **1.9.195**: provider universal probe (13 backend)
|
|
32
|
+
5. **1.9.196**: 7μΌ+/30μΌ+ recall + ScheduleWakeup miss detector
|
|
33
|
+
6. **1.9.197**: provider probe handoff μλ ν΅ν© (60λΆ μΊμ)
|
|
34
|
+
7. **1.9.198**: multi-agent consensus μ΄λ ₯ β best agent μΆμ²
|
|
35
|
+
8. **1.9.199**: last-handoff μ λ° μΈ‘μ + R-0001 κ°ν μλ¦Ό
|
|
36
|
+
|
|
37
|
+
### stress-v145 β 13/13 PASS
|
|
38
|
+
- λ§μΌμ€ν€ λ³΄κ³ μ κ²μ¦ 4 + μ±λ₯ 2 + λμ νκ· 7
|
|
39
|
+
- μ±λ₯: --version cold start avg **1022 ms** Β· MCP 54 λꡬ **789 ms**
|
|
40
|
+
|
|
41
|
+
### μλ release νλ¦
|
|
42
|
+
- main μλ push **62 λΌμ΄λ μ°μ** (1.9.140~200)
|
|
43
|
+
- npm publish μλ (1.9.178~)
|
|
44
|
+
|
|
45
|
+
---
|
|
46
|
+
|
|
47
|
+
## 1.9.199 β 2026-05-21
|
|
48
|
+
|
|
49
|
+
**β° wakeup miss μλ ν볡 κ°ν β last-handoff timestamp μ λ° μΈ‘μ + R-0001 λ£° (25λΆ) λλΉ κ°ν μλ¦Ό.**
|
|
50
|
+
|
|
51
|
+
μμ¨ λͺ¨λ 129 λΌμ΄λ. μ¬μ©μ λ³΄κ³ "22:01μ λΌμ΄λμ μλμ§μ
λμ§μμμ΄" λμ.
|
|
52
|
+
|
|
53
|
+
### 1. last-handoff timestamp κΈ°λ‘ (`.harness/last-handoff.json`)
|
|
54
|
+
- handoff μ§μ
μ μλ κΈ°λ‘ β `last` + `history` (μ΅κ·Ό 10κ°)
|
|
55
|
+
- ν¨μ: `_recordLastHandoff(root)` / `_getLastHandoffGap(root)` / `_lastHandoffPath(root)`
|
|
56
|
+
- κΈ°λ‘ μμ: 1) μ΄μ timestamp 보쑴 β 2) νμ¬ timestamp κΈ°λ‘ β 3) 보쑴λ κ°μΌλ‘ gap μΈ‘μ
|
|
57
|
+
|
|
58
|
+
### 2. κ°ν μμ¬ μλ¦Ό (1.9.196 task-log κΈ°λ° β 1.9.199 μ λ°)
|
|
59
|
+
**R-0001 μꡬ λ£° (25λΆ) λλΉ:**
|
|
60
|
+
- gap > 60λΆ β π΄ κ°ν μμ¬ ("μμ€ν
sleep / wakeup λλ½ νμ€")
|
|
61
|
+
- gap 35~60λΆ β β μμ¬ ("buffer μ΄κ³Ό, ν cycle λλ½ κ°λ₯μ±")
|
|
62
|
+
- gap β€ 30λΆ + history β₯ 2 β β μ μ
|
|
63
|
+
|
|
64
|
+
```
|
|
65
|
+
## β° ScheduleWakeup miss κ°ν μμ¬ (1.9.199) β μ΄μ handoff 90λΆ μ
|
|
66
|
+
R-0001 μꡬ λ£° (25λΆ) λλΉ 3Γ μ΄κ³Ό β μμ€ν
sleep / wakeup λλ½ νμ€
|
|
67
|
+
β ν볡: μ¬μ©μκ° "λ€μ λΌμ΄λ" μ
λ ₯ λλ leerness rule list λ‘ λ£° νμΈ
|
|
68
|
+
β handoff μ΄λ ₯: 09:30:21 β 10:55:14 β 12:25:33
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
### 3. λμ νκ· (1.9.193~198) β λͺ¨λ μ μ§
|
|
72
|
+
|
|
73
|
+
### 4. stress-v144 β 16/16 PASS
|
|
74
|
+
- last-handoff μΈ‘μ (5) + μμ μν¬μ€νμ΄μ€ ν΅ν© (2) + μ±λ₯ (2) + λμ νκ· (7)
|
|
75
|
+
- μ±λ₯: --version cold start avg **1065 ms** Β· MCP 54 λꡬ **717 ms**
|
|
76
|
+
|
|
77
|
+
### 5. λ€μΈ΅ redundancy (μ¬μ©μ λ³΄κ³ λμ)
|
|
78
|
+
μΈμ
λ΄ νμ± cron jobs:
|
|
79
|
+
- `3f617fbc` β Every 25 minutes (R-0001 sync)
|
|
80
|
+
- `33a4ed9f` β 3,28,53 * * * * (offset backup)
|
|
81
|
+
- ScheduleWakeup 1500s primary
|
|
82
|
+
|
|
83
|
+
### 6. μλ release νλ¦
|
|
84
|
+
- main μλ push **61 λΌμ΄λ μ°μ** (1.9.140~199)
|
|
85
|
+
- npm publish μλ (1.9.178~)
|
|
86
|
+
|
|
87
|
+
---
|
|
88
|
+
|
|
3
89
|
## 1.9.198 β 2026-05-21
|
|
4
90
|
|
|
5
91
|
**π€ BμΆ 9/10 β 9.5/10 β handoff multi-agent consensus μ΄λ ₯ κΈ°λ° best agent μλ μΆμ².**
|
package/README.md
CHANGED
|
@@ -2,7 +2,7 @@
|
|
|
2
2
|
|
|
3
3
|
> **AI μ½λ© μμ΄μ νΈμ κ±°μ§ μλ£Β·μ€λ³΅Β·λ§κ°Β·μΆ©λμ λ§μμ£Όλ κ²μΒ·κΈ°μ΅Β·νμ
CLI νλ€μ€.**
|
|
4
4
|
|
|
5
|
-
[](https://www.npmjs.com/package/leerness) [](https://www.npmjs.com/package/leerness) []() []() []() []() []() []() [-brightgreen)]() []() []() []() []() []()
|
|
6
6
|
|
|
7
7
|
```
|
|
8
8
|
ββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
@@ -12,9 +12,9 @@
|
|
|
12
12
|
β βββ ββββββ ββββββ ββββββββββββββββββββββββ ββββββββ β
|
|
13
13
|
β βββββββββββββββββββββββββββ ββββββ ββββββββββββββββββββββ β
|
|
14
14
|
β βββββββββββββββββββββββββββ ββββββ βββββββββββββββββββββ β
|
|
15
|
-
β v1.9.
|
|
15
|
+
β v1.9.200 AI Agent Reliability Harness + Sandbox β
|
|
16
16
|
β verify Β· remember Β· orchestrate Β· audit Β· sandbox Β· drift β
|
|
17
|
-
β
|
|
17
|
+
β π 200 λ§μΌμ€ν€ Β· λ§€νΈλ¦μ€ 96/100 Β· 130 λΌμ΄λ Β· 62 push μ°μ β
|
|
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.
|
|
10
|
+
const VERSION = '1.9.200';
|
|
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 μ²λ¦¬).
|
|
@@ -1662,6 +1662,44 @@ async function skillAutoCacheCmd(root, sub) {
|
|
|
1662
1662
|
if (c.expired) log(` β κ°±μ : leerness skill auto-cache refresh`);
|
|
1663
1663
|
}
|
|
1664
1664
|
|
|
1665
|
+
// 1.9.199: wakeup miss μλ ν볡 κ°ν β last-handoff timestamp κΈ°λ‘ + 25min κΈ°λ interval μ λ° μΈ‘μ
|
|
1666
|
+
// μ¬μ©μ λͺ
μ (1.9.198 νμ): "22:01μ λΌμ΄λμ μλμ§μ
λμ§μμμ΄"
|
|
1667
|
+
// 1.9.196 task-log mtime κΈ°λ° detector λ task-log κ° μμ£Ό μ μ
λ°μ΄νΈλλ©΄ false positive.
|
|
1668
|
+
// last-handoff.json μΆκ°λ‘ μ νλ β + R-0001 λ£° (25min) λλΉ actual gap μΈ‘μ .
|
|
1669
|
+
function _lastHandoffPath(root) { return path.join(root, '.harness', 'last-handoff.json'); }
|
|
1670
|
+
function _recordLastHandoff(root) {
|
|
1671
|
+
try {
|
|
1672
|
+
mkdirp(path.join(root, '.harness'));
|
|
1673
|
+
const fp = _lastHandoffPath(root);
|
|
1674
|
+
let history = [];
|
|
1675
|
+
if (exists(fp)) {
|
|
1676
|
+
try { const j = JSON.parse(read(fp)); if (Array.isArray(j.history)) history = j.history; } catch {}
|
|
1677
|
+
}
|
|
1678
|
+
const now = new Date().toISOString();
|
|
1679
|
+
history.push(now);
|
|
1680
|
+
// μ΅κ·Ό 10κ°λ§ μ μ§
|
|
1681
|
+
if (history.length > 10) history = history.slice(-10);
|
|
1682
|
+
writeUtf8(fp, JSON.stringify({ last: now, history }, null, 2));
|
|
1683
|
+
return true;
|
|
1684
|
+
} catch { return false; }
|
|
1685
|
+
}
|
|
1686
|
+
function _getLastHandoffGap(root) {
|
|
1687
|
+
try {
|
|
1688
|
+
const fp = _lastHandoffPath(root);
|
|
1689
|
+
if (!exists(fp)) return { hasLast: false };
|
|
1690
|
+
const j = JSON.parse(read(fp));
|
|
1691
|
+
if (!j.last) return { hasLast: false };
|
|
1692
|
+
const lastMs = new Date(j.last).getTime();
|
|
1693
|
+
const gapMs = Date.now() - lastMs;
|
|
1694
|
+
const gapMin = Math.floor(gapMs / 60000);
|
|
1695
|
+
// R-0001 μꡬ λ£°: 25λΆ (1500s). gap > 35λΆ (140% buffer) β wakeup miss μμ¬
|
|
1696
|
+
const expected = 25;
|
|
1697
|
+
const isMiss = gapMin > 35;
|
|
1698
|
+
const isLong = gapMin > 60;
|
|
1699
|
+
return { hasLast: true, lastAt: j.last, gapMin, expected, isMiss, isLong, history: j.history || [] };
|
|
1700
|
+
} catch { return { hasLast: false }; }
|
|
1701
|
+
}
|
|
1702
|
+
|
|
1665
1703
|
// 1.9.198: BμΆ (λ©ν° Sub-Agent μ€μΌμ€νΈλΌ) λ³΄κ° β handoff μμ task keyword λ§€μΉ best agent μΆμ²
|
|
1666
1704
|
// 1.9.193 μμ agents multi --execute κ²°κ³Όλ₯Ό lessons.md μ κΈ°λ‘ β μ΄λ₯Ό keyword λ§€μΉνμ¬ μΆμΆ
|
|
1667
1705
|
// μ¬μ©μ/AI κ° κ°μ task μ¬μλ μ "κ³Όκ±° best agent μ°μ μλ" μ¦μ μΈμ§
|
|
@@ -3317,6 +3355,11 @@ function memorySearch(root, query) {
|
|
|
3317
3355
|
|
|
3318
3356
|
function handoff(root) {
|
|
3319
3357
|
root = absRoot(root);
|
|
3358
|
+
// 1.9.199: handoff μ§μ
μ 1) μ΄μ timestamp 보쑴 β 2) νμ¬ timestamp κΈ°λ‘
|
|
3359
|
+
// detector κ° prior gap μ μ νν μΈ‘μ (overwrite μ κ° νμ). ν¨μ μ΅μλ¨μ μ μΈ.
|
|
3360
|
+
let _priorHandoffGap = { hasLast: false };
|
|
3361
|
+
try { _priorHandoffGap = _getLastHandoffGap(root); } catch {}
|
|
3362
|
+
try { _recordLastHandoff(root); } catch {}
|
|
3320
3363
|
// 1.9.96: --json μ΅μ
(ꡬ쑰ν μΆλ ₯, MCP ν΅ν© / μΈλΆ AI μΉν)
|
|
3321
3364
|
if (has('--json')) {
|
|
3322
3365
|
const result = {
|
|
@@ -3822,25 +3865,51 @@ function handoff(root) {
|
|
|
3822
3865
|
}
|
|
3823
3866
|
} catch {}
|
|
3824
3867
|
}
|
|
3825
|
-
// 1.9.196: ScheduleWakeup miss detector β μμ¨ λͺ¨λ μ¬μ©μ λͺ
μ "λͺ»μΌμ΄λλ κ²½μ° μ’
μ’
μμ"
|
|
3826
|
-
//
|
|
3868
|
+
// 1.9.196/199: ScheduleWakeup miss detector β μμ¨ λͺ¨λ μ¬μ©μ λͺ
μ "λͺ»μΌμ΄λλ κ²½μ° μ’
μ’
μμ"
|
|
3869
|
+
// 1.9.196: task-log mtime κΈ°λ° (60min+) β false positive κ°λ₯
|
|
3870
|
+
// 1.9.199: last-handoff.json μ λ° μΈ‘μ β R-0001 λ£° (25min) λλΉ gap μΈ‘μ
|
|
3827
3871
|
// λκΈ°: LEERNESS_NO_WAKEUP_MISS=1
|
|
3828
3872
|
if (process.env.LEERNESS_NO_WAKEUP_MISS !== '1' && !has('--quiet') && !has('--no-wakeup-miss')) {
|
|
3829
3873
|
try {
|
|
3830
|
-
|
|
3831
|
-
|
|
3832
|
-
|
|
3833
|
-
|
|
3834
|
-
|
|
3835
|
-
|
|
3836
|
-
|
|
3837
|
-
|
|
3838
|
-
|
|
3839
|
-
|
|
3840
|
-
|
|
3841
|
-
log(
|
|
3842
|
-
log(dim(`
|
|
3874
|
+
// 1.9.199 μ κ·: μ΄μ handoff μμ (overwrite μ 보쑴λ κ°) μ¬μ©
|
|
3875
|
+
const gapInfo = _priorHandoffGap;
|
|
3876
|
+
const isTty = process.stdout && process.stdout.isTTY;
|
|
3877
|
+
const yel = s => isTty ? `\x1b[33m${s}\x1b[0m` : s;
|
|
3878
|
+
const red = s => isTty ? `\x1b[31m${s}\x1b[0m` : s;
|
|
3879
|
+
const dim = s => isTty ? `\x1b[2m${s}\x1b[0m` : s;
|
|
3880
|
+
const grn = s => isTty ? `\x1b[32m${s}\x1b[0m` : s;
|
|
3881
|
+
if (gapInfo.hasLast) {
|
|
3882
|
+
// λ§μ§λ§ handoff μμ μκ³ μμ β μ νν μΈ‘μ (1.9.199)
|
|
3883
|
+
if (gapInfo.isLong) {
|
|
3884
|
+
// 60λΆ+ β κ°ν μλ¦Ό
|
|
3885
|
+
log(red(`## β° ScheduleWakeup miss κ°ν μμ¬ (1.9.199) β μ΄μ handoff ${gapInfo.gapMin}λΆ μ `));
|
|
3886
|
+
log(dim(` R-0001 μꡬ λ£° (25λΆ) λλΉ ${Math.floor(gapInfo.gapMin/25)}Γ μ΄κ³Ό β μμ€ν
sleep / wakeup λλ½ νμ€`));
|
|
3887
|
+
log(dim(` β ν볡: μ¬μ©μκ° "λ€μ λΌμ΄λ" μ
λ ₯ λλ leerness rule list λ‘ λ£° νμΈ`));
|
|
3888
|
+
log(dim(` β handoff μ΄λ ₯: ${(gapInfo.history || []).slice(-3).map(t => t.slice(11, 19)).join(' β ')}`));
|
|
3889
|
+
log('');
|
|
3890
|
+
} else if (gapInfo.isMiss) {
|
|
3891
|
+
// 35~60λΆ β μμ¬
|
|
3892
|
+
log(yel(`## β° ScheduleWakeup μ§μ° (1.9.199) β μ΄μ handoff ${gapInfo.gapMin}λΆ μ (λ£°: 25λΆ)`));
|
|
3893
|
+
log(dim(` Β±10λΆ buffer μ΄κ³Ό β wakeup ν cycle λλ½ κ°λ₯μ±`));
|
|
3843
3894
|
log('');
|
|
3895
|
+
} else if (gapInfo.gapMin >= 0 && gapInfo.gapMin <= 30) {
|
|
3896
|
+
// μ μ λ²μ (handoff_history.length >= 2 μΌ λλ§ μλ―Έ μμ β 첫 μ§μ
μ μΈ)
|
|
3897
|
+
if ((gapInfo.history || []).length >= 2) {
|
|
3898
|
+
log(dim(` β ScheduleWakeup cycle μ μ (gap ${gapInfo.gapMin}λΆ, λ£° 25λΆ β 1.9.199)`));
|
|
3899
|
+
}
|
|
3900
|
+
}
|
|
3901
|
+
} else {
|
|
3902
|
+
// last-handoff.json λΆμ¬ β 1.9.196 fallback (task-log mtime)
|
|
3903
|
+
const tlp = taskLogPath(root);
|
|
3904
|
+
if (exists(tlp)) {
|
|
3905
|
+
const ageMs = Date.now() - fs.statSync(tlp).mtimeMs;
|
|
3906
|
+
const ageMin = Math.floor(ageMs / 60000);
|
|
3907
|
+
if (ageMin >= 60) {
|
|
3908
|
+
const label = ageMin < 120 ? `${ageMin}λΆ` : (ageMin < 1440 ? `${Math.floor(ageMin/60)}μκ°` : `${Math.floor(ageMin/1440)}μΌ`);
|
|
3909
|
+
log(yel(`## β° ScheduleWakeup miss μμ¬ (1.9.196 fallback) β task-log λ§μ§λ§ ${label} μ `));
|
|
3910
|
+
log(dim(` 1.9.199 last-handoff.json 첫 κΈ°λ‘ β λ€μ handoff λΆν° μ ν μΈ‘μ `));
|
|
3911
|
+
log('');
|
|
3912
|
+
}
|
|
3844
3913
|
}
|
|
3845
3914
|
}
|
|
3846
3915
|
} catch {}
|
|
@@ -4253,6 +4322,7 @@ function handoffCmd(root) {
|
|
|
4253
4322
|
if (has('--all-apps') || arg('--include', null)) {
|
|
4254
4323
|
return _handoffWorkspace(absRoot(root));
|
|
4255
4324
|
}
|
|
4325
|
+
// 1.9.199: timestamp κΈ°λ‘/μΈ‘μ μ handoff() λ΄λΆμμ μν (μ€λ³΅ λ°©μ§)
|
|
4256
4326
|
// 1.9.37: drift μλ κ²½κ³ (λ©μΈ μμ΄μ νΈκ° leernessλ₯Ό μ μ μ μ°λ νμ κ°μ§)
|
|
4257
4327
|
// 1.9.38 (A): drift μκ³ μ .harness/agent-reminders.md μλ μμ± β λ©μΈ μμ΄μ νΈ ν둬ννΈμ νμλλλ‘.
|
|
4258
4328
|
// 1.9.38 (D): skip νμ νμ΅ β --no-drift-check λΉλ β₯5 μ μκ³ μν (1d β 2d).
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "leerness",
|
|
3
|
-
"version": "1.9.
|
|
3
|
+
"version": "1.9.200",
|
|
4
4
|
"description": "Leerness: λΉνκ΄΄ λ§μ΄κ·Έλ μ΄μ
, μλ λ²μ κ°μ§Β·μ
λ°μ΄νΈ, κ³ν/μ§ν/νΈλμ€ν μλν, κ²μΌλ¦Β·μν¬λ¦ΏΒ·μΈμ½λ© μλ κ°λ, Claude Code μ¬λμ ν΅ν©μ κ°μΆ νκ΅μ΄ μ°μ AI κ°λ° νλ€μ€.",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"leerness",
|