leerness 1.35.7 → 1.35.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 +26 -0
- package/README.md +14 -4
- package/bin/leerness.js +40 -3
- package/package.json +1 -1
- package/scripts/e2e.js +6 -2
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,31 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.35.9 — 2026-07-03 — 자체 적대적 FP 헌트: declared-pass 게이트를 완전-통과(N/N) 주장으로 한정 (1.35.7 후속 하드닝)
|
|
4
|
+
|
|
5
|
+
**1.35.7 에서 declared-pass 부풀림 게이팅을 넣은 뒤, 그 신규 게이트에 전용 FP/FN 헌트를 직접 돌림**(메모리 교훈: 「휴리스틱 적대적 하드닝 — 배포 전 bypass+FP 헌터」·「게시본 재실증」). 12-프로브 매트릭스(단일/`--json`/`--all`/`gate --claims` × 비율/카운트/spec·tap·jest 리포터/growth/lenient)를 게시본 1.35.8 에 실행 → **bypass(FN) 0, 정상 FP 0**, 단 1건의 진짜 false-positive 발견.
|
|
6
|
+
|
|
7
|
+
### 확정 FP (게시본 1.35.8 재현)
|
|
8
|
+
- **비-테스트 부분 비율 오탐**: evidence `"closed 2/5 passing PRs"`(테스트와 무관한 부분 비율) + 실행 1/1 → `declaredPass` 파서가 "2/5 passing" 을 테스트 통과 주장으로 추출 → 게이트가 1 < 2 로 **truthful 완료를 거짓 거부(exit 1)**. 검증 도구가 정직한 완료를 CI 에서 막는 최악 케이스(원래 FN 보다 신뢰 훼손 큼). 1.35.7 이 이 표시상 모호함을 게이팅으로 승격시키며 노출됨.
|
|
9
|
+
|
|
10
|
+
### 수정 (원칙적 — 위협모델 정렬)
|
|
11
|
+
- **완전-통과(N/N) 주장만 게이팅**: `_declaredFullPass = declaredPass.num === declaredPass.denom` 조건 추가. 위협모델은 거짓 "all green" 이므로 완전-통과 주장만 부풀림 판정. 부분 비율(N<M)은 완료-주장이 아니거나 비-테스트 → 게이트 제외(표시는 advisory 유지, "부분 비율 — 게이트 제외" 정직 라벨). **FN 무회귀**: 정직한 "8/12 passed" done 의 실제 부분-실행은 이미 `allPassed`(tests-failed)가 별도로 잡으므로 이 게이트가 불필요. 완전-통과 부풀림("3/3 주장 vs 2/2 실행")은 그대로 FAIL.
|
|
12
|
+
- 표시 라벨 정직화: 실행<주장이지만 부분 비율이라 게이트 제외인 경우 "실행 ≥ 주장" 오표기 대신 "부분 비율 — advisory, 게이트 제외" 로 표기.
|
|
13
|
+
|
|
14
|
+
### 검증
|
|
15
|
+
- selftest **269** (신규: N/N 게이트 종속 + 부분 비율 advisory 라벨). full e2e **382** (기존 declared-pass 케이스에 (7) 비-테스트 부분 비율 FP 가드 추가 — exit 0). 12-프로브 매트릭스 전부 OK(FN 0/FP 0)로 게시본 재실증 예정.
|
|
16
|
+
|
|
17
|
+
## 1.35.8 — 2026-07-03 — GPT5.5평가 잔여 제안 채택: 문서 drift 가드 + 전용 스캐너 병행 레시피 + 테스트 티어 안내 (UR-0017)
|
|
18
|
+
|
|
19
|
+
**GPT 5.5 Pro 평가 후속 라운드** — 1.35.7 에서 확정버그 3건을 수정했고, 이번엔 잔여 개선제안 중 저위험·고정직성 항목을 채택. 나머지(e2e 3-tier 분리 / minimal lazy-create / AST 검증기)는 UR-0014~0016 으로 백로그 등록.
|
|
20
|
+
|
|
21
|
+
### 채택 (제안⑤⑥ + ③문서파트)
|
|
22
|
+
- **문서 숫자 drift 자동가드 (제안⑤)**: selftest 가 README managed 섹션의 MCP 도구 수(`**N개 도구**`)를 `lib/mcp-tools` 실제 정의 수와 대조 — 사이트가 85↔86 으로 drift 했던 계열의 재발을 릴리스 게이트에서 차단.
|
|
23
|
+
- **전용 스캐너 병행 레시피 (제안⑥)**: README "Guidance vs enforcement" 에 gitleaks-action + leerness scan secrets 병행 워크플로 스니펫 추가. `scan secrets` human 출력에도 포지셔닝 정직 고지 1줄(편의 가드 — CI급 보장은 전용 스캐너 병행, ko/en) — README 만으론 CLI 사용자에게 닿지 않던 갭.
|
|
24
|
+
- **테스트 티어 안내 (제안③ 문서파트)**: README Maturity 에 npm test = 풀 릴리스 게이트(10분+, 의도된 설계) vs test:fast = 개발 루프(1분 미만) 명시. 스크립트 분리 자체는 UR-0014 별도 라운드.
|
|
25
|
+
|
|
26
|
+
### 검증
|
|
27
|
+
- selftest **268** (신규: README 도구 수 정합 + 레시피/고지/티어 문서 존재). full e2e (scan secrets 출력 1줄 추가 — 기존 단언과 충돌 없음 확인).
|
|
28
|
+
|
|
3
29
|
## 1.35.7 — 2026-07-03 — 19th GPT5.5pro 평가: verify-claim declared-pass 부풀림 게이팅 + spec 리포터 파싱 + json ok/reasons (UR-0013)
|
|
4
30
|
|
|
5
31
|
**웹 GPT 5.5 Pro 확장의 독립 평가보고서(1.35.6 게시본 대상) 검토 라운드**. 맹신 X 재현 결과 보고서의 헤드라인 버그가 **3경로 전부 실재** — 원인 분석의 소스 위치까지 정확했음. 검토 중 추가 발견 2건(자기모순 출력 + Node v26 파서 FN)도 함께 수정.
|
package/README.md
CHANGED
|
@@ -81,12 +81,22 @@ The generated workflow is production-grade: it **pins the leerness version** (re
|
|
|
81
81
|
|
|
82
82
|
Then make that check **required** in GitHub branch protection. Now a PR that skips verification (or whose claims fail) **cannot merge** — the gate runs independently of the agent, returns a non-zero exit code, and blocks. That is the difference between a guideline and a guardrail. For exact per-claim enforcement, run `leerness gate --claims` — it adds a 6th check that runs `verify-claim` on **every** completed task and fails the gate if any "done" task's evidence doesn't match reality (the default 5-check gate already blocks false-done via heuristics; `--claims` makes it precise).
|
|
83
83
|
|
|
84
|
+
For secrets, pair the gate with a **dedicated scanner** in the same workflow — leerness's `scan secrets` is a convenience guard (the same signal your agent sees locally), not a hard guarantee:
|
|
85
|
+
|
|
86
|
+
```yaml
|
|
87
|
+
# add to .github/workflows/leerness-gate.yml (or a separate job)
|
|
88
|
+
- uses: gitleaks/gitleaks-action@v2 # dedicated scanner — the hard-guarantee layer
|
|
89
|
+
- run: npx leerness@<pinned-version> scan secrets . --json # convenience layer — same check your agent runs locally
|
|
90
|
+
```
|
|
91
|
+
|
|
84
92
|
---
|
|
85
93
|
|
|
86
94
|
## Maturity — and why trying it is still cheap
|
|
87
95
|
|
|
88
96
|
Be honest with yourself before you depend on this: leerness is **early and largely solo-maintained**, developed mostly through autonomous AI rounds — so its own `selftest` + e2e suites are the primary quality signal, and external adoption is still small. Don't make it load-bearing on faith: **pin a version**, and treat the differentiated slice — `verify-claim` + the CI `gate` as a required check — as the part worth relying on.
|
|
89
97
|
|
|
98
|
+
(Contributor note: `npm test` is the full release gate — selftest + the entire e2e suite, **10+ minutes by design**. For a quick dev loop use `npm run test:fast` — selftest + smoke, under a minute.)
|
|
99
|
+
|
|
90
100
|
The asymmetry is what makes a trial reasonable anyway: MIT, **0 runtime dependencies**, offline-first, and all state is plain files in *your* repo. Lock-in is near zero — if it doesn't earn its place, remove the tool and your `task`/`decision`/`lesson` files stay. (For secret scanning specifically, mature dedicated tools like gitleaks/trufflehog exist — use those if you need a hard guarantee; leerness's `scan secrets` is a convenience guard, not a replacement.)
|
|
91
101
|
|
|
92
102
|
---
|
|
@@ -115,7 +125,7 @@ MIT
|
|
|
115
125
|
<!-- leerness:project-readme:start -->
|
|
116
126
|
## Leerness Project Harness
|
|
117
127
|
|
|
118
|
-
이 프로젝트는 Leerness v1.35.
|
|
128
|
+
이 프로젝트는 Leerness v1.35.9 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
119
129
|
|
|
120
130
|
### 정체성 — AI 에이전트 운영 레이어 (UR-0030)
|
|
121
131
|
|
|
@@ -169,7 +179,7 @@ leerness memory restore decision <date|title>
|
|
|
169
179
|
|
|
170
180
|
### MCP server (외부 AI 통합)
|
|
171
181
|
|
|
172
|
-
Leerness v1.35.
|
|
182
|
+
Leerness v1.35.9는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **86개 도구**를 노출:
|
|
173
183
|
|
|
174
184
|
```jsonc
|
|
175
185
|
// 카테고리별
|
|
@@ -190,7 +200,7 @@ Leerness v1.35.7는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code
|
|
|
190
200
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
191
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) 다음 라운드 예약.
|
|
192
202
|
|
|
193
|
-
현재 누적: **70 라운드 (1.9.40 → 1.35.
|
|
203
|
+
현재 누적: **70 라운드 (1.9.40 → 1.35.9)** · 매 라운드 GitHub release/태그 생성 · _reports/는 비공개 보존.
|
|
194
204
|
|
|
195
205
|
### 성능 가이드 (1.9.140 측정)
|
|
196
206
|
|
|
@@ -228,6 +238,6 @@ leerness release pack --close --auto-main-push
|
|
|
228
238
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
229
239
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
230
240
|
|
|
231
|
-
Last synced by Leerness v1.35.
|
|
241
|
+
Last synced by Leerness v1.35.9: 2026-07-03
|
|
232
242
|
<!-- leerness:project-readme:end -->
|
|
233
243
|
|
package/bin/leerness.js
CHANGED
|
@@ -32,7 +32,7 @@ const { _evidenceQuality, _parseEvidenceStats, _shellGuardAnalyze, _claimFileInG
|
|
|
32
32
|
// 1.9.295 (UR-0025 4단계): 정적 데이터 카탈로그 모듈 분리 (비파괴, require-based).
|
|
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
|
|
|
35
|
-
const VERSION = '1.35.
|
|
35
|
+
const VERSION = '1.35.9';
|
|
36
36
|
|
|
37
37
|
// 1.9.290 (UR-0037, Codex gpt-5.5 #4 수렴): CLI 전용 부작용은 require 시 실행하지 않는다.
|
|
38
38
|
// 이전: warning listener 제거 / NODE_OPTIONS 변경 / chcp IIFE 가 top-level 즉시 실행 → require('harness') 시 호스트 프로세스 오염.
|
|
@@ -2905,6 +2905,26 @@ function _selfTestCases() {
|
|
|
2905
2905
|
const jsonOk = src.includes('out.ok = out.reasons.length === 0') && src.includes('if (!out.ok) return process.exit(1)');
|
|
2906
2906
|
return parseOk && gateWired && jsonOk;
|
|
2907
2907
|
} },
|
|
2908
|
+
{ name: '19th GPT5.5평가 제안⑤⑥ (UR-0017): README MCP 도구 수 ↔ lib/mcp-tools 정합(문서 drift 가드) + 전용 스캐너 병행 레시피/포지셔닝/테스트 티어 문서화 (1.35.8)', run: () => {
|
|
2909
|
+
// (⑤) 문서 숫자 drift: README managed 섹션의 "**N개 도구**" 가 실제 MCP 도구 정의 수와 일치해야 함 (사이트 85↔86 drift 재발 방지 계열).
|
|
2910
|
+
const readme = read(path.join(__dirname, '..', 'README.md'));
|
|
2911
|
+
const m = readme.match(/\*\*(\d+)개 도구\*\*/);
|
|
2912
|
+
const tools = require('../lib/mcp-tools').length;
|
|
2913
|
+
const managedOk = !!m && parseInt(m[1], 10) === tools;
|
|
2914
|
+
// (⑥) 전용 스캐너 병행 레시피(README) + scan secrets 출력 포지셔닝 고지 + 테스트 티어 안내.
|
|
2915
|
+
const recipeOk = /gitleaks\/gitleaks-action/.test(readme) && /test:fast/.test(readme);
|
|
2916
|
+
const advisoryOk = /pair with a dedicated scanner \(gitleaks\/trufflehog\)/.test(read(__filename));
|
|
2917
|
+
return managedOk && recipeOk && advisoryOk;
|
|
2918
|
+
} },
|
|
2919
|
+
{ name: '자체 적대적 FP 헌트 (1.35.9): declared-pass 게이트는 완전-통과(N/N) 주장만 — 부분 비율(비-테스트) 오탐 차단 + 완전-통과 부풀림 무회귀', run: () => {
|
|
2920
|
+
const src = read(__filename);
|
|
2921
|
+
// 게이트가 _declaredFullPass(num===denom) 조건에 종속 — 부분 비율(N<M)은 게이팅 제외.
|
|
2922
|
+
const fullPassGuard = src.includes('const _declaredFullPass = !!(declaredPass && declaredPass.num === declaredPass.denom);')
|
|
2923
|
+
&& /_declaredPassMismatch = !lenient && _declaredFullPass &&/.test(src);
|
|
2924
|
+
// 표시 라벨은 부분 비율을 advisory(게이트 제외)로 정직 표기 — 실행<주장인데 "실행 ≥ 주장" 오표기 안 함.
|
|
2925
|
+
const honestLabel = src.includes('부분 비율 — advisory, 게이트 제외') && src.includes('partial ratio — advisory, not gated');
|
|
2926
|
+
return fullPassGuard && honestLabel;
|
|
2927
|
+
} },
|
|
2908
2928
|
{ name: 'honesty-check: AI 인식론적 정직성 3차원 + MCP/CLI/strict 통합 (사용자명시 1.9.305)', run: () => { const h = _epistemicHonestyCheck; const d1 = h('이 기능은 항상 정상 동작합니다').findings.some(f => f.dim === 'pretend-knowledge'); const d2 = h('아마 될 것 같습니다. 구현 완료했습니다').findings.some(f => f.dim === 'premature-judgment'); const d3 = h('이 API 의 rate limit 은 초당 5회입니다').findings.some(f => f.dim === 'no-info-gathering'); const clean = h('src/api.js 수정, 12/12 통과 (Exit: 0)').ok === true; const src = read(__filename); const wired = require('../lib/mcp-tools').some(t => t.name === 'leerness_honesty_check') && /if \(cmd === 'honesty-check'\)/.test(src) && /honestyFindings = _epistemicHonestyCheck/.test(src); return d1 && d2 && d3 && clean && wired; } },
|
|
2909
2929
|
{ name: 'exit code 일관성: fail()→exitCode 1 행위 + unknown 명령 안내 (UR-0045 / CV-5 행위화 1.9.366)', run: () => { if (typeof fail !== 'function') return false; const saved = process.exitCode; const _w = process.stdout.write; let setOk = false; try { process.stdout.write = () => true; process.exitCode = 0; fail('selftest probe'); setOk = process.exitCode === 1; } finally { process.stdout.write = _w; process.exitCode = saved; } const src = read(__filename); const dispatchOk = /알 수 없는 명령: \$\{cmd\}/.test(src); return setOk && dispatchOk; } },
|
|
2910
2930
|
{ name: 'brief: 프로젝트 청사진 set/show/export + README 개요 섹션 (UR-0055 사용자명시 1.9.307)', run: () => { const src = read(__filename); const fnOk = typeof briefCmd === 'function' && typeof _loadBrief === 'function' && typeof _briefBlueprint === 'function' && _BRIEF_FIELDS.length === 10; const b = { project: 'X', intro: 'i', purpose: 'p', problem: '', features: ['f1', 'f2'], stack: ['s'], architecture: '', users: [], success: [], nonGoals: [], currentState: '' }; const bp = _briefBlueprint(b, VERSION); const bpOk = /Blueprint/.test(bp) && /소개 \(Intro\)/.test(bp) && /f1/.test(bp) && /신규 프로젝트 시작 가이드/.test(bp); const rb = _briefReadmeBlock(b); const rbOk = rb.includes(BRIEF_START) && rb.includes(BRIEF_END) && /프로젝트 개요/.test(rb) && /\*\*목적\*\*/.test(rb); return fnOk && bpOk && rbOk && /if \(cmd === 'brief'\)/.test(src); } },
|
|
@@ -8238,6 +8258,10 @@ function scanSecrets(root, opts = {}) {
|
|
|
8238
8258
|
if (ignored.length) {
|
|
8239
8259
|
log(` ⓘ gitignored ${ignored.length}건 (커밋 제외 — 설계상 안전 보관, 비실패): ${[...new Set(ignored.map(f => f.file))].join(', ')}`);
|
|
8240
8260
|
}
|
|
8261
|
+
// 1.35.8 (UR-0017, GPT5.5평가 제안⑥): 포지셔닝 정직 고지 — 편의 가드임을 출력에서도 명시(README 만으론 CLI 사용자에게 안 닿음).
|
|
8262
|
+
log(_uiLang(root) === 'en'
|
|
8263
|
+
? ` ⓘ positioning: convenience guard for agent workflows — for CI-grade guarantees pair with a dedicated scanner (gitleaks/trufflehog). Recipe: README "Guidance vs enforcement".`
|
|
8264
|
+
: ` ⓘ 포지셔닝: 에이전트 워크플로용 편의 가드 — CI급 보장이 필요하면 전용 스캐너(gitleaks/trufflehog)와 병행하세요. 레시피: README "Guidance vs enforcement".`);
|
|
8241
8265
|
}
|
|
8242
8266
|
|
|
8243
8267
|
function encodingCheck(root, opts = {}) {
|
|
@@ -10674,7 +10698,13 @@ function verifyClaimCmd(root, taskId, opts = {}) {
|
|
|
10674
10698
|
// 이전: 3경로(human overallFail / --json exit / collect reasons) 모두 불일치를 감지·표시만 하고 exit 0 — 부풀린 주장이 플래그십을 통과 + 최종요약은 "일치 ✓" 자기모순.
|
|
10675
10699
|
// 주장 개수("N개")는 이미 게이팅(testCountMatch)되는데 비율 주장("N/M")만 안 되던 내부 비일관성 해소.
|
|
10676
10700
|
// 방향성 게이트(실행 pass ≥ 주장 pass 면 통과) — 테스트가 늘어난 정상 흐름을 벌하지 않음(testCountMatch 의 실측≥주장 규칙과 동일 철학). 완화: --lenient.
|
|
10677
|
-
|
|
10701
|
+
// 1.35.9 (자체 적대적 FP 헌트): declared-pass 게이트는 "전부 통과(N/N)" 완료-주장에만 적용.
|
|
10702
|
+
// FP 재현: evidence "closed 2/5 passing PRs"(비-테스트 부분 비율) + 실행 1/1 → 게이트가 truthful 완료를 거짓 거부(exit 1).
|
|
10703
|
+
// 원인: declaredPass 파서는 evidence 어디든 "N/M passing" 을 테스트 주장으로 추출 → 1.35.7 이 이 표시상 모호함을 게이팅으로 승격.
|
|
10704
|
+
// 수정: 위협모델은 거짓 "all green"(N/N) 이므로 완전-통과 주장만 게이팅. 부분 비율(N<M)은 완료-주장이 아니거나 비-테스트 → 제외(표시는 advisory 유지).
|
|
10705
|
+
// FN 무회귀: 정직한 "8/12 passed" done 의 실제 부분-실행은 allPassed(tests-failed)가 별도로 잡음(이 게이트 불필요).
|
|
10706
|
+
const _declaredFullPass = !!(declaredPass && declaredPass.num === declaredPass.denom);
|
|
10707
|
+
const _declaredPassMismatch = !lenient && _declaredFullPass && !!(runResult && !runResult.skipped && runResult.parsed && runResult.parsed.num < declaredPass.num);
|
|
10678
10708
|
|
|
10679
10709
|
// 1.33.2 (verify-claim --all): 집계 모드는 렌더/exit 없이 verdict 만 반환. 게이팅 부울은 아래 --json/human 경로와 동일 계산을 공유(분기 없음).
|
|
10680
10710
|
if (opts.collect) {
|
|
@@ -10791,7 +10821,14 @@ function verifyClaimCmd(root, taskId, opts = {}) {
|
|
|
10791
10821
|
if (runResult && !runResult.skipped) {
|
|
10792
10822
|
// 1.27.1 (13번째 외부리뷰 #3): exit 0 인데 테스트 비율을 못 파싱한 경우(예: 비-테스트 --test-cmd)를 '✓ all passed' 로 거짓표기하지 않음 — '실행됨, 테스트 수 미확인' 으로 정직 표기(판정/exit 불변 → 이색 테스트러너 FP 없음).
|
|
10793
10823
|
log(` - ${runResult.cmd || 'npm test'} ${t('실행', 'run')}: ${runTestsOk ? (runResult.parsed ? '✓ all passed' : t('✓ 실행됨 (exit 0) — 테스트 수 미확인', '✓ ran (exit 0) — test count unconfirmed')) : '✗ FAIL'}`);
|
|
10794
|
-
if (declaredPass)
|
|
10824
|
+
if (declaredPass) { // 1.35.7 (UR-0013): 자기모순 표기 제거 — 부풀림은 FAIL 라벨. 1.35.9: 부분 비율은 advisory(게이트 제외) 정직 표기.
|
|
10825
|
+
let _vsLabel;
|
|
10826
|
+
if (declaredPassMatchesActual) _vsLabel = '✓ pass';
|
|
10827
|
+
else if (_declaredPassMismatch) _vsLabel = t('✗ FAIL (주장이 실행 결과보다 부풀려짐)', '✗ FAIL (claim inflated vs run)');
|
|
10828
|
+
else if (_declaredFullPass) _vsLabel = t('⚠ 다름 (실행 ≥ 주장 — pass)', '⚠ differs (run ≥ claimed — pass)');
|
|
10829
|
+
else _vsLabel = t('⚠ 다름 (부분 비율 — advisory, 게이트 제외)', '⚠ differs (partial ratio — advisory, not gated)');
|
|
10830
|
+
log(` - ${t('주장과 실행 결과 일치', 'claimed matches run')}: ${_vsLabel}`);
|
|
10831
|
+
}
|
|
10795
10832
|
}
|
|
10796
10833
|
// 1.11.2 (UR-0175): optimism+정직성 — done 주장은 기본 게이팅(claimsChecked). 완화: --lenient.
|
|
10797
10834
|
if (claimsChecked) {
|
package/package.json
CHANGED
package/scripts/e2e.js
CHANGED
|
@@ -6848,9 +6848,13 @@ total++;
|
|
|
6848
6848
|
const r6 = cp.spawnSync(process.execPath, [CLI, 'verify-claim', 'T-0002', '--run-tests', '--test-cmd', 'echo Tests: 3 passed, 3 total', '--path', d], { encoding: 'utf8', timeout: 20000 });
|
|
6849
6849
|
const truthfulOk = r5.status === 0;
|
|
6850
6850
|
const growthOk = r6.status === 0;
|
|
6851
|
+
// (7) 1.35.9 FP 가드: 비-테스트 부분 비율("2/5 passing PRs") + 실행 1/1 → 게이트 제외(exit 0). 완전-통과 부풀림만 게이팅.
|
|
6852
|
+
cp.spawnSync(process.execPath, [CLI, 'task', 'update', 'T-0002', '--status', 'done', '--evidence', 'src/x.js implemented, x.test.js added; closed 2/5 passing PRs', '--path', d], { encoding: 'utf8', timeout: 15000 });
|
|
6853
|
+
const r7 = cp.spawnSync(process.execPath, [CLI, 'verify-claim', 'T-0002', '--run-tests', '--test-cmd', 'echo 1 passing', '--path', d], { encoding: 'utf8', timeout: 20000 });
|
|
6854
|
+
const partialRatioFpOk = r7.status === 0; // 부분 비율은 게이팅 안 함(오탐 차단)
|
|
6851
6855
|
fs.rmSync(d, { recursive: true, force: true });
|
|
6852
|
-
ok = inflatedFails && jsonOk && allOk && specParsed && truthfulOk && growthOk;
|
|
6853
|
-
if (!ok) console.log(` [dpm 디버그] inflated=${inflatedFails} json=${jsonOk} all=${allOk} spec=${specParsed} truthful=${truthfulOk} growth=${growthOk}`);
|
|
6856
|
+
ok = inflatedFails && jsonOk && allOk && specParsed && truthfulOk && growthOk && partialRatioFpOk;
|
|
6857
|
+
if (!ok) console.log(` [dpm 디버그] inflated=${inflatedFails} json=${jsonOk} all=${allOk} spec=${specParsed} truthful=${truthfulOk} growth=${growthOk} partialFP=${partialRatioFpOk}`);
|
|
6854
6858
|
} catch {}
|
|
6855
6859
|
console.log(ok ? '✓ B(1.35.7) UR-0013: declared-pass 부풀림 게이팅(human/json/--all) + spec 리포터 파싱 + 실행≥주장 무벌점' : '✗ declared-pass mismatch 게이팅 실패');
|
|
6856
6860
|
if (!ok) failed++;
|