leerness 1.36.8 → 1.36.9
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 +10 -0
- package/README.md +4 -4
- package/bin/leerness.js +19 -3
- package/lib/catalogs.js +3 -1
- package/package.json +1 -1
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,15 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.36.9 — 2026-07-09 — optimism [DB] FP 수정: SQL-migration 프로젝트의 정직한 done 주장 무오탐 (dogfood 백로그)
|
|
4
|
+
|
|
5
|
+
**stock-service 도그푸드에서 두 번 마주친 선재 FP 소진(깨끗한 1.36.2에서도 동일 재현 확인 — 이번 세션 회귀 아님).**
|
|
6
|
+
|
|
7
|
+
- 증상: `.sql` 마이그레이션만으로 구성된 정직한 done 주장(evidence 에 `migration` 언급)이 verify-claim/lazy-detect 의 optimism 검사에서 `[DB] 주장 있는데 코드 호출 흔적 없음` 으로 오탐 → 기본 게이트 false-fail.
|
|
8
|
+
- 원인(재현으로 확정): `_scanCodeForPatterns` 확장자 필터에 `.sql`/`.prisma` 부재(스캔 결과 0바이트) **그리고** DB codeRe 가 JS/ORM 관용구만 인식(raw SQL 미인식) — 둘 다 충족돼야 오탐이 사라짐.
|
|
9
|
+
- 수정: 스캐너 확장자 `+= sql|prisma|mjs|cjs` · DB codeRe `+= CREATE TABLE|ALTER TABLE|INSERT INTO|node:sqlite|DatabaseSync|better-sqlite3` (검출 관대화 — 1.12.4 다언어 확장과 같은 안전 방향).
|
|
10
|
+
- 정밀도 검증: 허위 DB 주장(코드에 DB 흔적 없음)은 여전히 `[DB]` 검출(FN 미발생, 행위 확인). selftest 283 (신규 행위 케이스: SQL 스캔 + 정직 무오탐 + 허위 검출 유지) + e2e 통과.
|
|
11
|
+
- 부수: `_detectOptimism`/`_scanCodeForPatterns` export(테스트 가능성, require.main 가드 패턴).
|
|
12
|
+
|
|
3
13
|
## 1.36.8 — 2026-07-09 — 정직성 marginal 소진 + 넛지 확장 (심층 감사 P3 완결)
|
|
4
14
|
|
|
5
15
|
**심층 정직성 감사(1.36.5)의 마지막 marginal P3 2건 소진 + handoff 넛지를 실사용 최다 명령으로 확장.**
|
package/README.md
CHANGED
|
@@ -125,7 +125,7 @@ MIT
|
|
|
125
125
|
<!-- leerness:project-readme:start -->
|
|
126
126
|
## Leerness Project Harness
|
|
127
127
|
|
|
128
|
-
이 프로젝트는 Leerness v1.36.
|
|
128
|
+
이 프로젝트는 Leerness v1.36.9 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
129
129
|
|
|
130
130
|
### 정체성 — AI 에이전트 운영 레이어 (UR-0030)
|
|
131
131
|
|
|
@@ -179,7 +179,7 @@ leerness memory restore decision <date|title>
|
|
|
179
179
|
|
|
180
180
|
### MCP server (외부 AI 통합)
|
|
181
181
|
|
|
182
|
-
Leerness v1.36.
|
|
182
|
+
Leerness v1.36.9는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **86개 도구**를 노출:
|
|
183
183
|
|
|
184
184
|
```jsonc
|
|
185
185
|
// 카테고리별
|
|
@@ -200,7 +200,7 @@ Leerness v1.36.8는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code
|
|
|
200
200
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
201
201
|
1) 다음 라운드 후보 선정 → 2) 코드 변경 → 3) stress-v* 신규 작성 + 누적 회귀 → 4) e2e 219/219 → 5) npm pack + git tag + GitHub release → 6) main 자동 push (1.9.140+) → 7) session close → 8) 다음 라운드 예약.
|
|
202
202
|
|
|
203
|
-
현재 누적: **70 라운드 (1.9.40 → 1.36.
|
|
203
|
+
현재 누적: **70 라운드 (1.9.40 → 1.36.9)** · 매 라운드 GitHub release/태그 생성 · _reports/는 비공개 보존.
|
|
204
204
|
|
|
205
205
|
### 성능 가이드 (1.9.140 측정)
|
|
206
206
|
|
|
@@ -238,6 +238,6 @@ leerness release pack --close --auto-main-push
|
|
|
238
238
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
239
239
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
240
240
|
|
|
241
|
-
Last synced by Leerness v1.36.
|
|
241
|
+
Last synced by Leerness v1.36.9: 2026-07-09
|
|
242
242
|
<!-- leerness:project-readme:end -->
|
|
243
243
|
|
package/bin/leerness.js
CHANGED
|
@@ -33,7 +33,7 @@ const { _evidenceQuality, _parseEvidenceStats, _shellGuardAnalyze, _claimFileInG
|
|
|
33
33
|
const { CAPABILITY_SURFACE, POWERFUL_COMMANDS, ADAPTERS, REUSE_CATEGORIES, REUSE_CHECKLIST, _DEFAULT_PLATFORM_CONSTRAINTS, _DEFAULT_DOMAIN_CATALOG, _TOOL_CATALOG, _LSP_LANG_PATTERNS, OPTIMISM_PATTERNS, BUILT_IN_PERSONAS, STRINGS, BUILTIN_CATALOG, ROADMAP_STATUS_LABEL, ROADMAP_STATUS_COLOR, SECRET_PATTERNS, MERGE_OVERWRITE_FILES, MINIMAL_SKIP_KEYS, REQUIRED_WORKSPACE_FILES, KEYWORD_STOPWORDS, SKILL_CATALOG_PRESETS } = require('../lib/catalogs'); // 1.9.344/368/369 (UR-0025): catalog 분리 · 1.11.4 (UR-0007): _TOOL_CATALOG
|
|
34
34
|
const { findCorruptedStateJson: _findCorruptedStateJson } = require('../lib/state-integrity'); // 1.36.1 (클린룸 리뷰 FN): .harness/*.json 상태 무결성 (audit/health/check 공유)
|
|
35
35
|
|
|
36
|
-
const VERSION = '1.36.
|
|
36
|
+
const VERSION = '1.36.9';
|
|
37
37
|
|
|
38
38
|
// 1.9.290 (UR-0037, Codex gpt-5.5 #4 수렴): CLI 전용 부작용은 require 시 실행하지 않는다.
|
|
39
39
|
// 이전: warning listener 제거 / NODE_OPTIONS 변경 / chcp IIFE 가 top-level 즉시 실행 → require('harness') 시 호스트 프로세스 오염.
|
|
@@ -4002,6 +4002,21 @@ function _selfTestCases() {
|
|
|
4002
4002
|
const nudgeInUpdate = /task updated: \$\{id\}`\);[\s\S]{0,200}_emitHandoffNudge\(root\)/.test(self); // update 경로 넛지 와이어
|
|
4003
4003
|
return encScopeOk && selfHealOk && noBareOk && nudgeInUpdate;
|
|
4004
4004
|
} },
|
|
4005
|
+
{ name: 'optimism [DB] FP 수정 (1.36.9, dogfood 백로그): SQL-migration만 있는 정직한 주장 무오탐 + 허위 주장 검출 유지 (행위)', run: () => {
|
|
4006
|
+
const os = require('os');
|
|
4007
|
+
const dir = fs.mkdtempSync(path.join(os.tmpdir(), 'lz-odb-'));
|
|
4008
|
+
try {
|
|
4009
|
+
fs.mkdirSync(path.join(dir, 'db'), { recursive: true });
|
|
4010
|
+
fs.writeFileSync(path.join(dir, 'db', '001_create.sql'), 'CREATE TABLE product (id INTEGER PRIMARY KEY, stock INTEGER NOT NULL);\n');
|
|
4011
|
+
const ct = _scanCodeForPatterns(dir);
|
|
4012
|
+
const scannedOk = ct.includes('CREATE TABLE'); // .sql 이 스캔됨
|
|
4013
|
+
const honest = _detectOptimism('db/001_create.sql 마이그레이션 적용 완료', ct);
|
|
4014
|
+
const noFp = !honest.some(s => s.kind === 'DB'); // 정직한 SQL 주장 무오탐
|
|
4015
|
+
const fake = _detectOptimism('사용자 데이터를 DB에 저장 완료, INSERT 500건', 'const x = 1;');
|
|
4016
|
+
const stillDetects = fake.some(s => s.kind === 'DB'); // 허위 주장 검출 유지(FN 없음)
|
|
4017
|
+
return scannedOk && noFp && stillDetects;
|
|
4018
|
+
} finally { try { fs.rmSync(dir, { recursive: true, force: true }); } catch { /* ignore */ } }
|
|
4019
|
+
} },
|
|
4005
4020
|
{ name: 'CLI 영어화 Phase 1 (1.20.2, UR-0010): _uiLang 해석(flag>env>manifest>ko) + 첫화면 _t 적용 (행위+소스)', run: () => {
|
|
4006
4021
|
const save = process.argv; const saveEnv = process.env.LEERNESS_LANG;
|
|
4007
4022
|
try {
|
|
@@ -11758,7 +11773,7 @@ function _scanCodeForPatterns(root) {
|
|
|
11758
11773
|
for (const e of entries) {
|
|
11759
11774
|
if (budget <= 0) return;
|
|
11760
11775
|
if (e.isDirectory()) { if (!SKIP.test(e.name) && !e.name.startsWith('.')) walk(path.join(p, e.name), depth + 1); continue; }
|
|
11761
|
-
if (!/\.(js|ts|jsx|tsx|gd|cs|py|rb|go|rs|java|php|kt|swift)$/i.test(e.name)) continue;
|
|
11776
|
+
if (!/\.(js|mjs|cjs|ts|jsx|tsx|gd|cs|py|rb|go|rs|java|php|kt|swift|sql|prisma)$/i.test(e.name)) continue; // 1.36.9: sql/prisma(+mjs/cjs) — SQL-migration만 있는 정직한 done 주장이 [DB] optimism 오탐되던 FP 수정
|
|
11762
11777
|
// 1.12.5 (15th 버그헌트 P2, UR-0019): stat-before-read — 이전엔 read() 후 budget 검사라 대형 파일 1개가 통째 메모리에 로드(200MB→RSS 464MB). 남은 budget 초과 파일은 읽지 않고 건너뜀.
|
|
11763
11778
|
try { const fp2 = path.join(p, e.name); if (fs.statSync(fp2).size > budget) continue; const t = read(fp2); combined += t + '\n'; budget -= t.length; } catch {}
|
|
11764
11779
|
}
|
|
@@ -21235,5 +21250,6 @@ module.exports = {
|
|
|
21235
21250
|
// 1.18.3 (UR-0003): 분야별 자기질문 품질 렌즈 — 단위 테스트. 1.19.2: 파일→도메인 매핑(완료-검증 advisory)
|
|
21236
21251
|
LENS_CATALOG, lensCmd, _lensDomainsForFiles, _mergeLensCatalog, _loadProjectLenses, _effectiveLensCatalog,
|
|
21237
21252
|
_isDbContentText, _anyDbContentInFiles, _withDbDomain,
|
|
21238
|
-
_handoffNudgeState, _getLastHandoffGap, _recordLastHandoff
|
|
21253
|
+
_handoffNudgeState, _getLastHandoffGap, _recordLastHandoff,
|
|
21254
|
+
_detectOptimism, _scanCodeForPatterns
|
|
21239
21255
|
};
|
package/lib/catalogs.js
CHANGED
|
@@ -239,7 +239,9 @@ const OPTIMISM_PATTERNS = [
|
|
|
239
239
|
codeRe: /\b(fetch\s*\(|http\.request|https\.request|axios\.|got\.|undici|node-fetch|requests\.|httpx|urllib|http\.client|net\/http|Net::HTTP|HTTParty|Faraday|HttpClient|http\.Get|http\.Post|http\.NewRequest|reqwest|curl_|HttpURLConnection|RestTemplate|URLSession)/i,
|
|
240
240
|
label: 'API/HTTP 호출' },
|
|
241
241
|
{ kind: 'DB', evidenceRe: /(DB에?\s*저장|insert\s+\d+|데이터베이스|SQL\s*(INSERT|UPDATE|DELETE)|migration|마이그레이션 적용)/i,
|
|
242
|
-
|
|
242
|
+
// 1.36.9 (dogfood FP): raw SQL(DDL/DML) + node:sqlite idiom 추가 — SQL-migration 파일만으로 구성된 정직한 done 주장이
|
|
243
|
+
// '[DB] 호출 흔적 없음' 으로 오탐되던 FP 수정(스캐너의 .sql/.prisma 확장과 짝). 검출 관대화 방향(1.12.4 선례).
|
|
244
|
+
codeRe: /\b(db\.|pg\.|pool\.|mysql\.|mongoose\.|prisma\.|sequelize|knex|sqlite3|MongoClient|createConnection|psycopg|sqlalchemy|cursor\.execute|django\.db|sqlx|gorm|database\/sql|ActiveRecord|jdbc|EntityManager|DbContext|mysqli|CREATE\s+TABLE|ALTER\s+TABLE|INSERT\s+INTO|node:sqlite|DatabaseSync|better-sqlite3)/i,
|
|
243
245
|
label: 'DB 호출' },
|
|
244
246
|
{ kind: 'Email', evidenceRe: /(이메일[^.\n]{0,30}(발송|전송|보냈|보냄|완료)|메일[^.\n]{0,30}(발송|전송|보냈|보냄)|sendMail|smtp\s*(전송|발송))/i,
|
|
245
247
|
codeRe: /\b(sendMail|nodemailer|smtp|@sendgrid|mailgun|aws-sdk\/ses|resend\.|smtplib|django\.core\.mail|ActionMailer|net\/smtp|Net::SMTP|SmtpClient|javax\.mail|JavaMailSender)/i,
|