leerness 1.35.5 → 1.35.6
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 +14 -0
- package/README.md +4 -4
- package/bin/leerness.js +21 -2
- package/lib/agents.js +11 -5
- package/package.json +1 -1
- package/scripts/e2e.js +10 -4
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,19 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.35.6 — 2026-07-02 — 18th 위임실증: codex-leerness 준수 라이브 검증 + dispatch harness 브리프 + bench stdin hang 수정
|
|
4
|
+
|
|
5
|
+
**위임 실증 라운드 (사용자 명시: "codex가 leerness를 참조하고 작업을 진행하는지 확인 후 고도화")**. 라이브 재현: leerness init 된 임시 프로젝트에 위임 룰(codex 구현/Claude 검수) 등록 → **leerness 를 전혀 언급하지 않은** 순수 코딩 태스크를 dispatch 레시피 그대로 codex(0.141)에 위임.
|
|
6
|
+
|
|
7
|
+
### 실증 결과 (79 exec 명령 전수 분석)
|
|
8
|
+
- **codex 는 AGENTS.md 경유로 leerness 를 자발 준수함 (강한 준수 확인)**: session-workflow/필수 읽기 순서 11개 파일 → handoff → drift check → scan secrets → route → task add → reuse find/impact → 구현 → node --test 실측 → task update(--evidence) → **verify-claim --run-tests 자기검증(테스트 명령 미지정 경고를 보고 --test-cmd 붙여 재검증까지)** → lens code/test → lazy detect → session close. progress-tracker 에 T-0002 done + 실측 증거 기록 확인.
|
|
9
|
+
|
|
10
|
+
### 수정 (실증에서 발견)
|
|
11
|
+
- **dispatch harness 위임 브리프 자동 접두 (`_harnessBrief`, 안전망)**: codex 준수는 (a) cwd=프로젝트 루트, (b) AGENTS.md 지원 CLI, (c) 자발 준수 3조건 의존 → dispatch 태스크 앞에 4단계 계약(handoff 적재 → task add → evidence 기록+verify-claim → session close)을 자동 접두. 셸 임베드 안전(backtick/달러/쌍따옴표-free). `--raw` 로 원문 위임.
|
|
12
|
+
- **agents bench codex stdin hang (확인, 실버그)**: `codex exec` 는 stdin 이 열린 파이프면 `Reading additional input from stdin...` 에서 EOF 를 무한 대기(라이브 재현 — 40바이트 출력으로 8분+ hang). bench 의 `cp.spawn(..., { shell: true })` 는 기본 stdio pipe 로 stdin 을 닫지 않아 codex 가 항상 타임아웃으로 왜곡됨 → `stdio: ['ignore','pipe','pipe']`. dispatch 안내에도 비대화형 spawn 시 stdin 닫기 경고 추가.
|
|
13
|
+
|
|
14
|
+
### 검증
|
|
15
|
+
- selftest **266** (신규: `_harnessBrief` 내용/셸-안전 + dispatch 접두 와이어 + bench stdio 가드). full e2e (dispatch 회귀 무영향 — 기존 테스트는 플래그/거부 단언). patch — npm 미배포(R-0011).
|
|
16
|
+
|
|
3
17
|
## 1.35.5 — 2026-06-27 — 17th 버그헌트: scan .json5/.jsonc FN + verify-claim git 매칭 정밀도
|
|
4
18
|
|
|
5
19
|
**비-graph 버그헌트(게시본 1.35.4 후, R-0011)**. Explore 에이전트가 낸 6개 후보를 **맹신 X 재현으로 검증** → 강한 후보 다수가 거짓 판명(멀티라인 시크릿·`test_`고엔트로피 FN은 실제 재현에서 이미 flagged; agent의 `api_secret`↔`secret` 매칭 가정도 word-boundary로 오류), **확정 2건만** 수정.
|
package/README.md
CHANGED
|
@@ -115,7 +115,7 @@ MIT
|
|
|
115
115
|
<!-- leerness:project-readme:start -->
|
|
116
116
|
## Leerness Project Harness
|
|
117
117
|
|
|
118
|
-
이 프로젝트는 Leerness v1.35.
|
|
118
|
+
이 프로젝트는 Leerness v1.35.6 하네스를 사용합니다. AI 에이전트는 작업 전 `leerness handoff`로 컨텍스트를 적재하고, 작업 후 `leerness check`/`leerness audit`/`leerness session close`를 수행해야 합니다.
|
|
119
119
|
|
|
120
120
|
### 정체성 — AI 에이전트 운영 레이어 (UR-0030)
|
|
121
121
|
|
|
@@ -169,7 +169,7 @@ leerness memory restore decision <date|title>
|
|
|
169
169
|
|
|
170
170
|
### MCP server (외부 AI 통합)
|
|
171
171
|
|
|
172
|
-
Leerness v1.35.
|
|
172
|
+
Leerness v1.35.6는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code · Cursor · Codex CLI 등 외부 AI에 **86개 도구**를 노출:
|
|
173
173
|
|
|
174
174
|
```jsonc
|
|
175
175
|
// 카테고리별
|
|
@@ -190,7 +190,7 @@ Leerness v1.35.5는 stdio JSON-RPC MCP server를 내장합니다 — Claude Code
|
|
|
190
190
|
`<<autonomous-loop-dynamic>>` 신호만 보내면 AI가:
|
|
191
191
|
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
192
|
|
|
193
|
-
현재 누적: **70 라운드 (1.9.40 → 1.35.
|
|
193
|
+
현재 누적: **70 라운드 (1.9.40 → 1.35.6)** · 매 라운드 GitHub release/태그 생성 · _reports/는 비공개 보존.
|
|
194
194
|
|
|
195
195
|
### 성능 가이드 (1.9.140 측정)
|
|
196
196
|
|
|
@@ -228,6 +228,6 @@ leerness release pack --close --auto-main-push
|
|
|
228
228
|
- `.harness/session-handoff.md`: 다음 세션 인수인계 (자동 작성)
|
|
229
229
|
- `.harness/lessons.md` / `decisions.md` / `rules.md`: 영구 메모리 (5 surface)
|
|
230
230
|
|
|
231
|
-
Last synced by Leerness v1.35.
|
|
231
|
+
Last synced by Leerness v1.35.6: 2026-07-03
|
|
232
232
|
<!-- leerness:project-readme:end -->
|
|
233
233
|
|
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.6';
|
|
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') 시 호스트 프로세스 오염.
|
|
@@ -2874,6 +2874,17 @@ function _selfTestCases() {
|
|
|
2874
2874
|
{ name: '_withLock/_updateRun: lost-update 락(O_EXCL+재진입) + 적용 (UR-0043 외부리뷰 1.9.303)', run: () => { const src = read(__filename); const fnOk = typeof _withLock === 'function' && typeof _sleepSyncMs === 'function' && typeof _updateRun === 'function'; const reentrant = /if \(_heldLocks\.has\(lockPath\)\) return fn\(\)/.test(src); const excl = /fs\.openSync\(lockPath, 'wx'\)/.test(src); const applied = /const id = _withLock\(progressPath\(root\)/.test(src) && /_updateRun\(root, curId/.test(src); return fnOk && reentrant && excl && applied; } },
|
|
2875
2875
|
{ name: 'lib/analyzers: 분석/검증 함수 4종 모듈 단일출처 분리 (UR-0025 1.9.304)', run: () => { const m = require('../lib/analyzers'); return m._evidenceQuality === _evidenceQuality && m._shellGuardAnalyze === _shellGuardAnalyze && m._parseEvidenceStats === _parseEvidenceStats && m._claimFileInGit === _claimFileInGit && !/function _evidenceQuality\(evidence\) \{/.test(read(__filename)) && !/function _shellGuardAnalyze\(cmd, ctx\) \{/.test(read(__filename)); } },
|
|
2876
2876
|
{ name: '17th헌트: _claimFileInGit bare-basename 충돌 차단 + scan .json5/.jsonc 포함 (1.35.5)', run: () => { const a = require('../lib/analyzers'); const collisionFixed = a._claimFileInGit('src/test.js', new Set(['test.js'])) !== true; const forwardOk = a._claimFileInGit('test.js', new Set(['src/test.js'])) === true; const exactOk = a._claimFileInGit('src/a.js', new Set(['src/a.js'])) === true; const nestedReverseOk = a._claimFileInGit('x/src/a.js', new Set(['src/a.js'])) === true; const src = read(__filename); const json5Ext = src.includes("'.js" + "on5'") && src.includes("'.js" + "onc'"); return collisionFixed && forwardOk && exactOk && nestedReverseOk && json5Ext; } },
|
|
2877
|
+
{ name: '18th 위임실증: _harnessBrief 계약 브리프(handoff/task/verify-claim/session close, backtick·달러-free) + dispatch 접두 와이어 + bench stdin ignore (1.35.6)', run: () => {
|
|
2878
|
+
// (1) 브리프 내용: 위임 계약 4단계 포함 + 셸 임베드 안전(backtick/달러 금지 — command substitution 차단).
|
|
2879
|
+
const b = _harnessBrief();
|
|
2880
|
+
const briefOk = typeof b === 'string' && b.includes('leerness handoff .') && b.includes('task add') && b.includes('verify-claim') && b.includes('session close') && b.includes('--evidence') && !b.includes('`') && !b.includes('$') && !b.includes('"');
|
|
2881
|
+
// (2) dispatch 와이어: lib/agents.js 가 --raw 옵트아웃으로 브리프를 접두하고, DI 로 _harnessBrief 를 받음.
|
|
2882
|
+
const agentsSrc = read(path.join(__dirname, '..', 'lib', 'agents.js'));
|
|
2883
|
+
const wired = /has\('--raw'\)[\s\S]{0,120}_harnessBrief\(\) \+ task/.test(agentsSrc) && /_harnessBrief,/.test(read(__filename));
|
|
2884
|
+
// (3) bench stdin hang 수정: codex exec 가 열린 stdin 파이프에서 EOF 대기(실측) → spawn stdio ignore.
|
|
2885
|
+
const stdinFixed = agentsSrc.includes("{ shell: true, stdio: ['ignore', 'pipe', 'pipe'] }");
|
|
2886
|
+
return briefOk && wired && stdinFixed;
|
|
2887
|
+
} },
|
|
2877
2888
|
{ 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; } },
|
|
2878
2889
|
{ 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; } },
|
|
2879
2890
|
{ 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); } },
|
|
@@ -12516,6 +12527,14 @@ async function setupAgentsCmd(root, opts = {}) {
|
|
|
12516
12527
|
|
|
12517
12528
|
// 1.9.152: 단일 agent dispatch 명령 빌더 — agents dispatch (단일) + agents multi (복수) 가 공유
|
|
12518
12529
|
// 1.9.270: model 인자 추가 — 역할(roles) 기반 dispatch 시 provider 별 모델 플래그 주입 (없으면 기존 동작 그대로).
|
|
12530
|
+
// 1.35.6 (18th 위임실증): 위임 프롬프트 harness 계약 브리프 — dispatch 태스크 앞에 접두.
|
|
12531
|
+
// 실증(2026-07-02, codex 0.141): AGENTS.md 로드 시 codex 는 handoff→task add→verify-claim→session close 를 자발 준수(79 exec 재현).
|
|
12532
|
+
// 단 cwd 가 프로젝트 루트가 아니거나 AGENTS.md 미지원 CLI 면 계약 미전달 → 프롬프트 접두가 안전망.
|
|
12533
|
+
// 셸 명령 문자열에 임베드되므로 backtick/달러 금지 (command substitution/변수 확장 방지) — 인용은 작은따옴표만.
|
|
12534
|
+
function _harnessBrief() {
|
|
12535
|
+
return "[leerness 위임 프로토콜] 시작: 'leerness handoff .' 로 컨텍스트/active rules 적재 후 'leerness task add' 로 이 작업 등록. 완료 전: evidence(수정 파일 경로 + 실제 테스트 결과)를 'leerness task update <T-ID> --status done --evidence ...' 로 기록하고 'leerness verify-claim <T-ID> --run-tests' 로 자기검증. 종료: 'leerness session close .' 실행. --- 작업: ";
|
|
12536
|
+
}
|
|
12537
|
+
|
|
12519
12538
|
function _dispatchCommand(agentId, task, writeMode, model) {
|
|
12520
12539
|
const q = String(task || '').replace(/"/g, '\\"');
|
|
12521
12540
|
const m = model ? String(model).replace(/"/g, '') : '';
|
|
@@ -12535,7 +12554,7 @@ function _dispatchCommand(agentId, task, writeMode, model) {
|
|
|
12535
12554
|
|
|
12536
12555
|
const _agents = require('../lib/agents');
|
|
12537
12556
|
// 1.9.424 (UR-0025/UR-0125 큰 핸들러 모듈화 9번째): agentsCmd → lib/agents.js (DI 위임, rest→array)
|
|
12538
|
-
function agentsCmd(root, sub, ...args) { return _agents.agentsCmd(root, sub, args, { VERSION, has, arg, _agentSlashHint, _allProviders, _checkAgent, _cliChat, _dispatchCommand, _loadEnvFile, _normalizeRole, _policyEnforce, _readUserProviders, _recommendAgent, _recordRun, _resolveRole, _shellQuoteArg, lessonsPath, taskLogPath }); }
|
|
12557
|
+
function agentsCmd(root, sub, ...args) { return _agents.agentsCmd(root, sub, args, { VERSION, has, arg, _agentSlashHint, _allProviders, _checkAgent, _cliChat, _dispatchCommand, _harnessBrief, _loadEnvFile, _normalizeRole, _policyEnforce, _readUserProviders, _recommendAgent, _recordRun, _resolveRole, _shellQuoteArg, lessonsPath, taskLogPath }); }
|
|
12539
12558
|
|
|
12540
12559
|
function personaCmd(root, sub, idOrName, ...rest) {
|
|
12541
12560
|
root = absRoot(root || process.cwd());
|
package/lib/agents.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
// lib/agents.js — agents 오케스트레이션 핸들러 (UR-0025/UR-0125 큰 핸들러 모듈화 9번째, 1.9.424)
|
|
2
|
-
// bin/leerness.js 에서 agentsCmd(442줄) 분리. DI: harness 고유 의존(VERSION, has, arg, _agentSlashHint, _allProviders, _checkAgent, _cliChat, _dispatchCommand, _loadEnvFile, _normalizeRole, _policyEnforce, _readUserProviders, _recommendAgent, _recordRun, _resolveRole, _shellQuoteArg, lessonsPath, taskLogPath) 주입.
|
|
2
|
+
// bin/leerness.js 에서 agentsCmd(442줄) 분리. DI: harness 고유 의존(VERSION, has, arg, _agentSlashHint, _allProviders, _checkAgent, _cliChat, _dispatchCommand, _harnessBrief, _loadEnvFile, _normalizeRole, _policyEnforce, _readUserProviders, _recommendAgent, _recordRun, _resolveRole, _shellQuoteArg, lessonsPath, taskLogPath) 주입.
|
|
3
3
|
// io 프리미티브는 ./io, EXTERNAL_AGENTS 는 ./agent-registry, cp/path/fs 빌트인.
|
|
4
4
|
// 시그니처 (root, sub, ...args) → (root, sub, args[], deps): rest 를 배열 인자로 받아 재귀에 deps 전달. 동작 무변경.
|
|
5
5
|
'use strict';
|
|
@@ -10,7 +10,7 @@ const { log, ok, warn, fail, failJson, today, now, absRoot, exists, read, readBu
|
|
|
10
10
|
const { EXTERNAL_AGENTS, AGENT_SLASH_COMMANDS } = require('./agent-registry');
|
|
11
11
|
|
|
12
12
|
function agentsCmd(root, sub, args = [], deps = {}) {
|
|
13
|
-
const { VERSION, has, arg, _agentSlashHint, _allProviders, _checkAgent, _cliChat, _dispatchCommand, _loadEnvFile, _normalizeRole, _policyEnforce, _readUserProviders, _recommendAgent, _recordRun, _resolveRole, _shellQuoteArg, lessonsPath, taskLogPath } = deps;
|
|
13
|
+
const { VERSION, has, arg, _agentSlashHint, _allProviders, _checkAgent, _cliChat, _dispatchCommand, _harnessBrief, _loadEnvFile, _normalizeRole, _policyEnforce, _readUserProviders, _recommendAgent, _recordRun, _resolveRole, _shellQuoteArg, lessonsPath, taskLogPath } = deps;
|
|
14
14
|
root = absRoot(root || process.cwd());
|
|
15
15
|
// 1.9.435 (11th 외부평가 Codex P2, UR-0137): dispatch/multi task 파싱 — flag 값이 task 본문에 흡수되던 버그 수정.
|
|
16
16
|
// 상위(bin)에서 args 는 '--to' flag 만 제거되고 값(codex)은 positional 로 남아 기존 filter 가 task 에 흡수시켰음.
|
|
@@ -284,9 +284,13 @@ function agentsCmd(root, sub, args = [], deps = {}) {
|
|
|
284
284
|
if (roleModel) log(`# 🎭 모델: ${roleModel} (역할 기반 라우팅, 1.9.270)`);
|
|
285
285
|
log('');
|
|
286
286
|
// 1.9.270: _dispatchCommand 로 통일 (roleModel 주입) — 명령 빌더 단일화
|
|
287
|
-
|
|
287
|
+
// 1.35.6 (18th 위임실증): harness 계약 브리프 자동 접두 — codex 실측(0.141)에서 AGENTS.md 로드 시 준수는 확인됐으나,
|
|
288
|
+
// cwd 가 프로젝트 루트가 아니거나 AGENTS.md 미지원 CLI(aider/qwen 등)면 계약이 전달되지 않음 → 프롬프트 접두가 안전망. --raw 로 원문 위임.
|
|
289
|
+
const dispatchTask = (has('--raw') || typeof _harnessBrief !== 'function') ? task : (_harnessBrief() + task);
|
|
290
|
+
log(_dispatchCommand(target, dispatchTask, writeMode, roleModel));
|
|
291
|
+
if (!has('--raw') && typeof _harnessBrief === 'function') log(`# ℹ harness 위임 브리프 자동 접두 (1.35.6) — 원문만 위임하려면 --raw`);
|
|
288
292
|
if (target === 'claude' && writeMode) log(`# ⚠ --dangerously-skip-permissions: 도구 권한 자동 승인 (파일 수정 가능)`);
|
|
289
|
-
if (target === 'codex') { log(`# ℹ codex는 PowerShell 경유 — POSIX /tmp 경로는 C:\\tmp\\로 해석됨`); if (writeMode) log(`# ⚠ --dangerously-bypass-approvals-and-sandbox: sandbox 우회`); }
|
|
293
|
+
if (target === 'codex') { log(`# ℹ codex는 PowerShell 경유 — POSIX /tmp 경로는 C:\\tmp\\로 해석됨`); log(`# ⚠ 비대화형 spawn 시 stdin 을 닫고 실행 — 열린 파이프면 codex 가 'Reading additional input from stdin...' EOF 대기로 hang (1.35.6 실측)`); if (writeMode) log(`# ⚠ --dangerously-bypass-approvals-and-sandbox: sandbox 우회`); }
|
|
290
294
|
if (target === 'agy' && writeMode) log(`# ⚠ --yolo: 워크스페이스 파일 직접 수정 가능`);
|
|
291
295
|
if (target === 'grok' && writeMode) log(`# ⚠ grok --yolo: 자동 승인 (배포판에 따라 플래그 상이 가능)`);
|
|
292
296
|
// 1.9.266 (UR-0021 2단계): 대상 에이전트의 슬래시 명령 힌트 — sub-agent 작업 시 알맞은 슬래시 명령 참조
|
|
@@ -355,7 +359,9 @@ function agentsCmd(root, sub, args = [], deps = {}) {
|
|
|
355
359
|
cmdArgs = ['copilot', 'suggest', qTask];
|
|
356
360
|
cmd = 'gh';
|
|
357
361
|
}
|
|
358
|
-
|
|
362
|
+
// 1.35.6 (18th 위임실증): stdin 'ignore' — codex exec 는 stdin 이 열린 파이프면 'Reading additional input from stdin...' 에서
|
|
363
|
+
// EOF 를 무한 대기해 항상 타임아웃으로 왜곡됨(라이브 재현). 인자 모드 CLI 는 stdin 불필요 → 닫고 spawn.
|
|
364
|
+
const r = cp.spawn(cmd, cmdArgs, { shell: true, stdio: ['ignore', 'pipe', 'pipe'] });
|
|
359
365
|
let stdout = '', stderr = '';
|
|
360
366
|
r.stdout.on('data', d => { stdout += d; });
|
|
361
367
|
r.stderr.on('data', d => { stderr += d; });
|
package/package.json
CHANGED
package/scripts/e2e.js
CHANGED
|
@@ -6493,13 +6493,19 @@ total++;
|
|
|
6493
6493
|
try {
|
|
6494
6494
|
const d = fs.mkdtempSync(path.join(os.tmpdir(), 'leerness-disp-'));
|
|
6495
6495
|
cp.spawnSync(process.execPath, [CLI, 'init', d, '--yes', '--language', 'ko'], { encoding: 'utf8', timeout: 30000 });
|
|
6496
|
-
const
|
|
6496
|
+
const env = { ...process.env, LEERNESS_ENABLE_CODEX: '1' };
|
|
6497
|
+
const r = cp.spawnSync(process.execPath, [CLI, 'agents', 'dispatch', 'REVIEWTASK', '--to', 'codex', '--path', d], { encoding: 'utf8', timeout: 20000, env });
|
|
6497
6498
|
const out = r.stdout || '';
|
|
6498
|
-
//
|
|
6499
|
-
|
|
6499
|
+
// 1.35.6: 기본은 harness 브리프가 접두되므로 task 는 "... 작업: REVIEWTASK" 끝에 그대로(코덱스/경로 흡수 없음).
|
|
6500
|
+
const briefOk = /작업: REVIEWTASK"/.test(out) && !/REVIEWTASK codex"/.test(out) && !/REVIEWTASK.*tmp/.test(out);
|
|
6501
|
+
// --raw 는 1.9.435 원형 보존 — task 가 정확히 "REVIEWTASK" 로만 인용.
|
|
6502
|
+
const rRaw = cp.spawnSync(process.execPath, [CLI, 'agents', 'dispatch', 'REVIEWTASK', '--to', 'codex', '--raw', '--path', d], { encoding: 'utf8', timeout: 20000, env });
|
|
6503
|
+
const outRaw = rRaw.stdout || '';
|
|
6504
|
+
const rawOk = /"REVIEWTASK"/.test(outRaw) && !/"REVIEWTASK codex"/.test(outRaw) && !/REVIEWTASK.*tmp/.test(outRaw) && !/위임 프로토콜/.test(outRaw);
|
|
6505
|
+
ok = briefOk && rawOk;
|
|
6500
6506
|
fs.rmSync(d, { recursive: true, force: true });
|
|
6501
6507
|
} catch {}
|
|
6502
|
-
console.log(ok ? '✓ B(1.9.435) UR-0137: agents dispatch task 에 --to/경로 값 흡수 없음' : '✗ agents dispatch flag bleed');
|
|
6508
|
+
console.log(ok ? '✓ B(1.9.435/1.35.6) UR-0137: agents dispatch task 에 --to/경로 값 흡수 없음 (브리프 접두 + --raw 원형)' : '✗ agents dispatch flag bleed');
|
|
6503
6509
|
if (!ok) failed++;
|
|
6504
6510
|
}
|
|
6505
6511
|
|