leerness 1.27.0 → 1.29.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.
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "leerness",
3
- "version": "1.27.0",
3
+ "version": "1.29.0",
4
4
  "description": "Leerness: 비파괴 마이그레이션, 자동 버전 감지·업데이트, 계획/진행/핸드오프 자동화, 게으름·시크릿·인코딩 자동 가드, Claude Code 슬래시 통합을 갖춘 한국어 우선 AI 개발 하네스.",
5
5
  "keywords": [
6
6
  "leerness",
package/scripts/e2e.js CHANGED
@@ -6230,10 +6230,18 @@ total++;
6230
6230
  const hEn = out(cp.spawnSync(process.execPath, [CLI, 'health', '--language', 'en', '--path', d], { encoding: 'utf8', timeout: 20000 }));
6231
6231
  const hKo = out(cp.spawnSync(process.execPath, [CLI, 'health', '--path', d], { encoding: 'utf8', timeout: 20000 }));
6232
6232
  const healthOk = /## Security/.test(hEn) && !H.test(hEn) && /## 보안/.test(hKo);
6233
+ // ⑥ (1.27.2 Phase 10) drift check 출력: en 영어(한글 0, --auto-fix 제외) + ko 기본 한글 보존
6234
+ const drEn = out(cp.spawnSync(process.execPath, [CLI, 'drift', 'check', d, '--language', 'en'], { encoding: 'utf8', timeout: 20000 }));
6235
+ const drKo = out(cp.spawnSync(process.execPath, [CLI, 'drift', 'check', d], { encoding: 'utf8', timeout: 20000 }));
6236
+ const driftOk = /signal \| age \| threshold/.test(drEn) && !H.test(drEn) && /신호 \| age \| 임계/.test(drKo);
6237
+ // ⑦ (1.28.2 Phase 10c) doctor: en 영어(한글 0) + ko 기본 한글 보존
6238
+ const docEn = out(cp.spawnSync(process.execPath, [CLI, 'doctor', '--language', 'en'], { encoding: 'utf8', timeout: 20000, cwd: d }));
6239
+ const docKo = out(cp.spawnSync(process.execPath, [CLI, 'doctor'], { encoding: 'utf8', timeout: 20000, cwd: d }));
6240
+ const doctorOk = /install\/environment diagnosis/.test(docEn) && !H.test(docEn) && /설치\/환경 진단/.test(docKo);
6233
6241
  fs.rmSync(d, { recursive: true, force: true });
6234
- ok = lensKoOk && lensEnOk && noLeak && stOk && healthOk;
6242
+ ok = lensKoOk && lensEnOk && noLeak && stOk && healthOk && driftOk && doctorOk;
6235
6243
  } catch {}
6236
- console.log(ok ? '✓ B(1.25.1/1.25.2) i18n 행위: --language en 런타임 영어(lens/health) + ko 기본 보존 + --language positional 무누출 + status 에러 en/ko (UR-0010)' : '✗ i18n 행위 회귀 가드 실패');
6244
+ console.log(ok ? '✓ B(1.25.1/1.25.2/1.27.2/1.28.2) i18n 행위: --language en 런타임 영어(lens/health/drift/doctor) + ko 기본 보존 + --language positional 무누출 + status 에러 en/ko (UR-0010)' : '✗ i18n 행위 회귀 가드 실패');
6237
6245
  if (!ok) failed++;
6238
6246
  }
6239
6247
 
@@ -6270,5 +6278,40 @@ total++;
6270
6278
  if (!ok) failed++;
6271
6279
  }
6272
6280
 
6281
+ // 1.27.1 (13번째 외부리뷰 정직성 후속 회귀가드): audit 미초기화 모순출력 차단 + verify-claim no-parse 정직표기 (양방향 무회귀).
6282
+ total++;
6283
+ {
6284
+ let ok = false;
6285
+ try {
6286
+ const d = fs.mkdtempSync(path.join(os.tmpdir(), 'leerness-rev13b-'));
6287
+ const out = (r) => (r.stdout || '') + (r.stderr || '');
6288
+ // #2 audit 미초기화: design/reuse 모순 출력 없이 요약 직행 + exit 1 + --json not_initialized
6289
+ fs.mkdirSync(path.join(d, 'uninit'));
6290
+ const au = cp.spawnSync(process.execPath, [CLI, 'audit', path.join(d, 'uninit')], { encoding: 'utf8', timeout: 15000 });
6291
+ const auClean = au.status === 1 && !/design guide|reuse-map/.test(out(au)) && /Audit summary/.test(out(au));
6292
+ const auj = cp.spawnSync(process.execPath, [CLI, 'audit', path.join(d, 'uninit'), '--json'], { encoding: 'utf8', timeout: 15000 });
6293
+ let aujOk = false; try { const j = JSON.parse(auj.stdout); aujOk = j.healthy === false && (j.findings || []).some(f => f.kind === ('not_' + 'initialized')); } catch {}
6294
+ // #2 회귀: 정상 프로젝트 audit 는 체크 계속 수행
6295
+ cp.spawnSync(process.execPath, [CLI, 'init', d, '--yes'], { encoding: 'utf8', timeout: 30000 });
6296
+ const auReal = out(cp.spawnSync(process.execPath, [CLI, 'audit', d], { encoding: 'utf8', timeout: 15000 }));
6297
+ const auRealOk = /Audit summary/.test(auReal) && /gitignore|design|reuse/.test(auReal);
6298
+ // #3 verify-claim 비-테스트 --test-cmd → 거짓 'all passed' 아님(정직 표기)
6299
+ fs.mkdirSync(path.join(d, 'src'), { recursive: true });
6300
+ fs.writeFileSync(path.join(d, 'src', 'x.js'), 'module.exports={};\n');
6301
+ fs.writeFileSync(path.join(d, 'x.test.js'), 'test();\n');
6302
+ cp.spawnSync(process.execPath, [CLI, 'task', 'add', 'x', '--path', d], { encoding: 'utf8', timeout: 15000 });
6303
+ cp.spawnSync(process.execPath, [CLI, 'task', 'update', 'T-0002', '--status', 'done', '--evidence', 'src/x.js implemented, x.test.js added', '--path', d], { encoding: 'utf8', timeout: 15000 });
6304
+ const vcNon = out(cp.spawnSync(process.execPath, [CLI, 'verify-claim', 'T-0002', '--run-tests', '--test-cmd', 'echo hi', '--path', d], { encoding: 'utf8', timeout: 20000 }));
6305
+ const vcNonOk = /미확인|unconfirmed/.test(vcNon) && !/echo hi.*all passed/.test(vcNon);
6306
+ // #3 회귀: 진짜 N/N 테스트 → all passed 유지
6307
+ const vcReal = out(cp.spawnSync(process.execPath, [CLI, 'verify-claim', 'T-0002', '--run-tests', '--test-cmd', 'echo Tests: 2 passed, 2 total', '--path', d], { encoding: 'utf8', timeout: 20000 }));
6308
+ const vcRealOk = /all passed/.test(vcReal);
6309
+ fs.rmSync(d, { recursive: true, force: true });
6310
+ ok = auClean && aujOk && auRealOk && vcNonOk && vcRealOk;
6311
+ } catch {}
6312
+ console.log(ok ? '✓ B(1.27.1) 13th 리뷰 정직성: audit 미초기화 모순출력 차단(+정상 무회귀) + verify-claim no-parse 정직표기(+진짜테스트 무회귀)' : '✗ 13th 리뷰 정직성 후속 회귀가드 실패');
6313
+ if (!ok) failed++;
6314
+ }
6315
+
6273
6316
  console.log(`\nE2E result: ${total - failed}/${total} passed · ${((Date.now() - _e2eStart) / 1000).toFixed(0)}s`);
6274
6317
  if (failed > 0) process.exit(1);