dsh-session-guard 3.2.2 → 3.2.4

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.ko.md CHANGED
@@ -1,133 +1,143 @@
1
- # 변경 기록
2
-
3
- `dsh-session-guard`의 주요 변경 사항을 기록합니다. 버전은 시맨틱 버저닝을 따릅니다.
4
-
5
- - [English changelog](./CHANGELOG.md)
6
- - [日本語 changelog](./CHANGELOG.ja.md)
7
- - [한국어 changelog](./CHANGELOG.ko.md)
8
-
9
- ## 0.4.0 — 2026-09-18 (잘못된 버전 번호, 3.0.0으로 대체됨)
10
-
11
- ### 수정
12
-
13
- - **버전 식별**: 본 라인은 `0.4.0`으로 배포되었지만 `dsh.plugin.json`과 본 변경 기록은 이미
14
- `3.0.0`을 표기하고 있어, 하나의 산출물에 두 개의 버전 번호가 존재했습니다. `package.json`을
15
- `3.0.0`으로 통일하여 패키지 버전·매니페스트 버전·변경 기록이 일치합니다. npm 버전은 불변이므로
16
- `0.4.0`은 역사적 기록으로 남깁니다. `3.0.0` 배포 후에는 `dist-tag dsh-0.1.5`를 `3.0.0`으로
17
- 다시 지정해야 합니다.
18
- - **문서**: README/INSTALL(zh/en/ja/ko)이 형제 라인을 `main`에 있다고 설명하던 것을 수정.
19
- 0.1.2 라인의 릴리스 브랜치는 **`legacy/0.1.2`**(npm dist-tag `dsh-0.1.2`, 버전 `0.3.1`)이며
20
- `main`은 `0.2.0-beta.1`에서 동결되었습니다. INSTALL.zh/ja/ko의 중복된
21
- 브랜치 조각을 수정하고, dist-tag를 명시한 설치 명령을 기재했습니다.
22
- "2.x / 3.x"는 **라인 통칭**이며 버전 번호가 아님을 명시.
23
-
24
- ### 비고
25
-
26
- - **소스 변경 없음**(`3.0.0` 대비). `0.4.0`은 동일 트리의 패키징 전용 배포입니다.
27
-
28
- ## 3.0.0 — 2026-09-14
29
-
30
- ### 변경
31
-
32
- - **DSH v0.1.5-rc.2 전용 라인(`compat/0.1.5`).** `engines.dsh`와 `dsh-client-*` peer 범위를
33
- `>=0.1.5-rc.2 <0.2.0-0`으로 좁혔습니다(semver 프리릴리스 규칙상 기존 `>=0.1.0-rc.7`은
34
- `0.1.5-rc.2`와 일치하지 않음). `dsh.plugin.json`에 `engines.dsh`를 추가했습니다. 구버전
35
- 호스트용으로는 `main`의 2.x / 0.2.x 라인이 계속 유지됩니다.
36
- - **`session.events` → `snapshotEvents()`.** DSH 0.1.5에서 `session.events` 배열 접근자가
37
- 제거됨에 따라(compatibility-guide §20.3) `pause-gate.js`는 듀얼 패스 헬퍼로 세션 이벤트를
38
- 읽습니다: 우선 `snapshotEvents()`, 방어적으로 구 `events` 배열로 폴백, 둘 다 없으면 `null`
39
- (fail-open). 대상은 `findToolOutcome`과 `lastUserPrompt` 두 곳뿐이며 이벤트 타입 매칭은
40
- 불변입니다.
41
-
42
- ### 변경 없음
43
-
44
- - 나머지 연동면은 전부 무변경: 자체 webServer prefix 라우트(`/session-guard/rpc`),
45
- `settings.register`, `settings.plugin.item` 슬롯, 클라이언트 주입,
46
- `llm.listConfigurableProviders()`는 공개된 0.1.5-rc.2 번들 기준으로 검증 완료
47
- (`tools/check-api-drift.ps1`, 필수 어설션 12/12).
48
-
49
- ### 보류
50
-
51
- - 실제 DSH 0.1.5-rc.2 호스트에서의 라이브 스모크(perm-gate 0.1.5 라인과 동일 상태).
52
-
53
- ## 0.2.0-beta.2 — 2026-09-13
54
-
55
- ### 수정 (DSH 0.1.5 호환 — `compat/0.1.5` 브랜치)
56
-
57
- - **재개 큐잉 듀얼 경로.** DSH 0.1.5에서는 Inbox가 agent-loop의 읽기 전용 프로젝션으로
58
- 바뀌어 `agent.followup`이 존재하지 않을 수 있습니다. 재개 시 `agent.followup` →
59
- `agent.send` → warn 강등(예외 없음) 순으로 시도합니다.
60
- - **재개 메시지 `source`에 `form: 'instructions'` 추가** (0.1.5 `ContextFormed` 계약;
61
- 구버전은 알 수 없는 필드를 무시합니다).
62
- - **`webServer.register` try/catch 보호**: 라우트 등록 실패는 로그만 남기고 `apply`에서
63
- 예외를 던져 호스트 플러그인 로딩을 깨뜨리지 않습니다.
64
- - 0.1.5-rc.2 소스 기준 `WebRoute`(exact/prefix + SSE) 계약이 불변임을 확인했습니다.
65
- 클라이언트 `fetch('/session-guard/...')`에 `/api` 접두사는 불필요합니다.
66
-
67
- ## 0.2.0-beta.1 — 2026-09-10
68
-
69
- ### 추가
70
-
71
- - **step급 게이트(`agent/pre-step`)**: 피크 시간에 턴 경계에서 중단하는 대신 **다음 step의 모델 요청 전에** 턴을 보류합니다. 세션은 다음 `agent/pre-step`까지 진행하고 거기서 게이트가 닫힙니다(설정 `stepLevelPause`, 기본 on). 오피크에는 **그 자리에서** 재개되며 followup 메시지가 필요 없습니다. 게이트 조건: 피크(북경 시간) + 주말 아님 + `step > 1` + 대상 provider가 공식(`providerGuard`) + 요청급 hold 아님 + 이번 피크 구간에서 스킵 아님. 신규 모듈 `src/step-gate.js`(순수 `decideStepHold` + hold / release / abort / timeout 엔진).
72
- - **`stepResume` 포트 + RPC + `/resume`**: `sessionGuard.stepResume(sessionId, {bypass})`, `POST /session-guard/rpc {action:'stepResume'}`, `/resume` 모두 게이트를 해제합니다. 수동 재개는 해당 피크 구간 동안 게이트를 중단합니다.
73
- - **타임아웃 승격**: `stepGateTimeoutMs`(기본 300000)로 게이트를 해제하고 **턴급 force 일시정지로 승격**합니다. 긴 피크에서도 교착이 없고 "5분마다 1 step" 누수도 없습니다.
74
- - **"⏸ 일시정지" 버튼**(클라이언트, slot `conversation.input.right`, id `session-guard-pause`, order 20 — input-traffic 동결 버튼 왼쪽). 1초마다 `/session-guard/state`를 폴링하며, 미보류 시 비활성, 보류 시 `stepResume`을 호출합니다. 배지는 order 40으로 이동하고 step 보류 수를 표시합니다.
75
- - **신규 설정**: `stepLevelPause`, `stepGateTimeoutMs`.
76
- - **신규 상태**: `GET /session-guard/state`가 `paused: { step, turn }`과 `stepGate: { held, since, bypass }`를 반환하고, `/status`는 `stepHeld`, `/diag`는 `stepGate`를 반환합니다. 서비스 포트 `state().paused`는 호환을 위해 불리언 유지(신규 필드 `pausedStep`).
77
-
78
- ### 수정
79
-
80
- - **step 보류와 턴급 일시정지의 교착**: `pauseTask` / `resumeTask` / `cancelTask`가 먼저 step 게이트를 해제합니다. step 보류는 `agent/pre-step`에 있어 `assistant/message` / `tool/result`가 영원히 오지 않으므로, `safe` 일시정지가 무한 대기하고 `paused`도 영속화되지 않았습니다.
81
-
82
- ### 변경
83
-
84
- - **피크 진입 시 실행 중 턴을 중단하지 않습니다**(`stepLevelPause` on일 때 `onEnterPeak`는 `stopNextTurn` 대신 step 게이트를 arm). off일 때는 기존 턴급 동작 그대로입니다.
85
- - input-traffic 동결 버튼 라벨이 **"동결 후 추가"**로 바뀌었고(`冻结追加` / `Freeze & append` / `凍結して追加`), 재개 라벨은 **"재개 후 추가"**(`恢复追加` / `Resume & append` / `再開して追加`)입니다 — 턴을 동결하면서 큐를 보존하는 동작으로, 일시정지 버튼과는 다릅니다.
86
- - **일시정지 버튼이 토글이 되었습니다**: "일시정지" / "재개" (회색 비활성 상태 제거). "일시정지"는 새 `stepPause`를 호출해 **다음 step 경계**에서 세션을 보류합니다(step 1도 대상, 피크/provider 제한 없음). "재개"는 `stepResume`. 신규 포트 메서드 `sessionGuard.stepPause(sessionId)`.
87
- - **SSE push**: 새 라우트 `GET /session-guard/events?session=<id>`가 step 게이트 상태 변화를 즉시 전달 — 피크에서 자동으로 닫히는 순간 버튼이 "재개"로 바뀝니다. 10초 폴링은 폴백으로 남습니다. `/state`는 `paused.manual`과 `stepGate.manual`을 반환합니다.
88
- - **스타일을 input-traffic 컴포저 버튼과 맞췄습니다**(높이 24px / 반경 6px / 12px 글꼴 / 동일 border·hover·pressed 토큰). 버튼과 상태 배지 모두. 스타일은 `<style data-plugin-css="session-guard-client">`로 한 번만 주입.
89
-
90
- ## Unreleased
91
-
92
- ### 추가
93
-
94
- - **공식 소스 2차 판정(피크 × 대상 provider)**: 피크 시간에는 대상 라우트가 DeepSeek 공식 소스일 때만 차단하고, 로컬/서드파티 provider는 정상 실행. 판정 순서는 명시 `officialProviders` id 목록 → 실시간 `baseURL` 엔드포인트 → catalog 내장 엔드포인트(pi-ai의 `deepseek`) → 내장 id(`deepseek-official`)이며 `matchedBy`를 반환. 신규 모듈: `src/provider.js`(순수), `src/provider-directory.js`, `src/deferrals.js`, `src/request-guard.js`, `src/targets.js`, `src/wiring.js`.
95
- - **요청급 백스톱(`agent/request`)**: 피크 진입 후 시작된 세션, 도중에 공식 소스로 전환된 세션을 포착(30s tick은 전환 시점에 `running`이던 세션만 처리). 기본 `hold`는 오류 없이 보류하고 피크 종료 순간 해제(`msUntilOffPeak`); `error`는 식별 가능한 `PEAK_DEFERRED`를 던지고 연기 큐에 기록.
96
- - **새 설정**: `providerGuard`, `officialProviders`, `officialBaseURLs`, `deferredResume`, `deferredResumeText`, `deferredMode`, `deferredMaxHoldMs`(기본 6h), `guardSubagents`.
97
- - **새 라우트**: `GET /session-guard/provider?provider=<id>`(판정 진단). `/session-guard/status`가 `providerGuard` / `held` / `deferred` 반환.
98
- - **드리프트 가드** `tools/check-api-drift.ps1`(4개 tag에서 필수 API 존재 검증).
99
-
100
- ### 변경
101
-
102
- - **DSH 이중 버전 지원(0.1.0-rc.7 … 0.1.2-rc.1)**: 하나의 산출물로 `dsh-v0.1.1-rc.2`와 `dsh-v0.1.2-rc.1` 지원.
103
- - **설정 표면은 교집합 API만**: `settings.register` + `settings.get`. `installSection`(0.1.2+)과 제거된 `installSettingsSection`은 사용하지 않음. 선택적 API는 특성 감지 후 강등.
104
- - **`src/retry.js`는 정확한 `PEAK_DEFERRED`만 단락**: 429 / `RATE_LIMIT` / `TRANSPORT` / 타임아웃은 여전히 일시적으로 처리. DSH 전역 재시도(`dsh-llm-retry`)는 불변.
105
- - 배지가 "피크·공식만"과 "피크·전체 정지"를 구분.
106
-
107
- ## 0.1.4 — 2026-09-09
108
-
109
- ### 변경
110
-
111
- - **공개 베타**(`0.1.4-beta.1`): 이중 버전 라인의 베타 채널용으로 버전 표기·README 호환 표·패키지 메타데이터 정비.
112
-
113
- ## 0.1.1 — 2026-08-24
114
-
115
- ### 추가
116
-
117
- - **백엔드 자동 재시도(D9)**: `turn/end` 일시적 실패(error/429/max-tokens)는 적응형 백오프의 `followup(retryText)`로 자동 재개; 영구 실패(인증/잔액/모델/컨텍스트 제한)는 중지; 사용자 개입 또는 성공 턴에서 연속 실패 카운트 리셋.
118
- - **동결/게이트 양보**: `isFrozen(sessionId)`가 참일 때 재시도 건너뜀, 세션 게이트를 우회하지 않음.
119
-
120
- ### 변경
121
-
122
- - `sessionGuard` 중복 포트가 `state(sessionId)`를 노출하여 `{ queueLocked, lockReason, paused, taskControlAvailable, taskControl }` 반환.
123
- - HTTP 라우트 `GET /session-guard/diag`가 재시도 상태를 포함한 런타임 진단 반환.
124
-
125
- ### 수정
126
-
127
- - 주말 감지를 벌거벗은 `getUTCDay()`에서 `Intl.DateTimeFormat`(설정된 타임존 사용)으로 변경, 베이징 타임존 8시간 경계 버그 수정.
128
-
129
- ## 0.1.0 — 2026-08-18
130
-
131
- ### 추가
132
-
133
- - 최초 릴리스: 피크 자동 일시정지(글로벌), 주말 모드, `sessionGuard` 중복 포트 + RPC 브리지 기반 세션별 동결/재개, 커스텀 세션 게이트, 설정 패널.
1
+ # 변경 기록
2
+
3
+ `dsh-session-guard`의 주요 변경 사항을 기록합니다. 버전은 시맨틱 버저닝을 따릅니다.
4
+
5
+ - [English changelog](./CHANGELOG.md)
6
+ - [日本語 changelog](./CHANGELOG.ja.md)
7
+ - [한국어 changelog](./CHANGELOG.ko.md)
8
+
9
+ ## 3.2.4 — 2026-09-27
10
+
11
+ ### Fixed
12
+ - **세션 포맷 v4 대응(호스트 >= 0.1.7-rc.1)**: 세션 기록 3곳에서 v4 호스트가 거부하는 구형 서명 `source: { kind: 'plugin', plugin: 'session-guard' }` 사용을 중단하고 producer-owned kind로 변경했습니다(`SessionFormatError`로 라운드 전체가 실패하던 문제 수정):
13
+ - 지연 재개 notice 주입(`src/wiring.js`)
14
+ - 자동 재시도 notice 주입(`src/retry.js`)
15
+ - 일시정지 해제 followup(`src/pause-gate.js`, ```kind: `plugin:${pluginId}````)
16
+ - **tool-result v4 native 대응(N1)**: `src/pause-gate.js`의 `findToolOutcome`은 v4 일급 `role:'tool'` 메시지(메시지 최상위 `toolCallId`/`isError`)를 우선 읽습니다. v3 `tool-result` 블록 경로는 역사 호환으로 유지. 미대응 시 일시정지 중 실패한 도구를 재개 시 "완료됨"으로 오판하는 조용한 오류를 수정. `src/tool-call-id.js`도 native 최상위 id 최우선. 0.1.1/0.1.2 시대 헤더 주기를 삼형상 세대표로 정정.
17
+ `form` 등 나머지 필드는 불변. 기존 구형 서명 행은 호스트 자체의 v3→v4 마이그레이션이 승격하므로 히스토리 데이터는 재작성하지 않습니다. 근거: `@deepseek-ai/dsh-session-format-v3-to-v4@0.1.7-rc.2`는 `source.kind`가 비어 있지 않고 `'plugin'`이 아닌지만 검증합니다.
18
+
19
+ ## 0.4.0 — 2026-09-18 (잘못된 버전 번호, 3.0.0으로 대체됨)
20
+
21
+ ### 수정
22
+
23
+ - **버전 식별**: 본 라인은 `0.4.0`으로 배포되었지만 `dsh.plugin.json`과 본 변경 기록은 이미
24
+ `3.0.0`을 표기하고 있어, 하나의 산출물에 두 개의 버전 번호가 존재했습니다. `package.json`을
25
+ `3.0.0`으로 통일하여 패키지 버전·매니페스트 버전·변경 기록이 일치합니다. npm 버전은 불변이므로
26
+ `0.4.0`은 역사적 기록으로 남깁니다. `3.0.0` 배포 후에는 `dist-tag dsh-0.1.5`를 `3.0.0`으로
27
+ 다시 지정해야 합니다.
28
+ - **문서**: README/INSTALL(zh/en/ja/ko)이 형제 라인을 `main`에 있다고 설명하던 것을 수정.
29
+ 0.1.2 라인의 릴리스 브랜치는 **`legacy/0.1.2`**(npm dist-tag `dsh-0.1.2`, 버전 `0.3.1`)이며
30
+ `main`은 `0.2.0-beta.1`에서 동결되었습니다. INSTALL.zh/ja/ko의 중복된
31
+ 브랜치 조각을 수정하고, dist-tag를 명시한 설치 명령을 기재했습니다.
32
+ "2.x / 3.x"는 **라인 통칭**이며 버전 번호가 아님을 명시.
33
+
34
+ ### 비고
35
+
36
+ - **소스 변경 없음**(`3.0.0` 대비). `0.4.0`은 동일 트리의 패키징 전용 배포입니다.
37
+
38
+ ## 3.0.0 — 2026-09-14
39
+
40
+ ### 변경
41
+
42
+ - **DSH v0.1.5-rc.2 전용 라인(`compat/0.1.5`).** `engines.dsh`와 `dsh-client-*` peer 범위를
43
+ `>=0.1.5-rc.2 <0.2.0-0`으로 좁혔습니다(semver 프리릴리스 규칙상 기존 `>=0.1.0-rc.7`은
44
+ `0.1.5-rc.2`와 일치하지 않음). `dsh.plugin.json`에 `engines.dsh`를 추가했습니다. 구버전
45
+ 호스트용으로는 `main`의 2.x / 0.2.x 라인이 계속 유지됩니다.
46
+ - **`session.events` → `snapshotEvents()`.** DSH 0.1.5에서 `session.events` 배열 접근자가
47
+ 제거됨에 따라(compatibility-guide §20.3) `pause-gate.js`는 듀얼 패스 헬퍼로 세션 이벤트를
48
+ 읽습니다: 우선 `snapshotEvents()`, 방어적으로 구 `events` 배열로 폴백, 둘 다 없으면 `null`
49
+ (fail-open). 대상은 `findToolOutcome`과 `lastUserPrompt` 두 곳뿐이며 이벤트 타입 매칭은
50
+ 불변입니다.
51
+
52
+ ### 변경 없음
53
+
54
+ - 나머지 연동면은 전부 무변경: 자체 webServer prefix 라우트(`/session-guard/rpc`),
55
+ `settings.register`, `settings.plugin.item` 슬롯, 클라이언트 주입,
56
+ `llm.listConfigurableProviders()`는 공개된 0.1.5-rc.2 번들 기준으로 검증 완료
57
+ (`tools/check-api-drift.ps1`, 필수 어설션 12/12).
58
+
59
+ ### 보류
60
+
61
+ - 실제 DSH 0.1.5-rc.2 호스트에서의 라이브 스모크(perm-gate 0.1.5 라인과 동일 상태).
62
+
63
+ ## 0.2.0-beta.2 — 2026-09-13
64
+
65
+ ### 수정 (DSH 0.1.5 호환 — `compat/0.1.5` 브랜치)
66
+
67
+ - **재개 큐잉 듀얼 경로.** DSH 0.1.5에서는 Inbox가 agent-loop의 읽기 전용 프로젝션으로
68
+ 바뀌어 `agent.followup`이 존재하지 않을 수 있습니다. 재개 시 `agent.followup` →
69
+ `agent.send` → warn 강등(예외 없음) 순으로 시도합니다.
70
+ - **재개 메시지 `source`에 `form: 'instructions'` 추가** (0.1.5 `ContextFormed` 계약;
71
+ 구버전은 알 수 없는 필드를 무시합니다).
72
+ - **`webServer.register` try/catch 보호**: 라우트 등록 실패는 로그만 남기고 `apply`에서
73
+ 예외를 던져 호스트 플러그인 로딩을 깨뜨리지 않습니다.
74
+ - 0.1.5-rc.2 소스 기준 `WebRoute`(exact/prefix + SSE) 계약이 불변임을 확인했습니다.
75
+ 클라이언트 `fetch('/session-guard/...')`에 `/api` 접두사는 불필요합니다.
76
+
77
+ ## 0.2.0-beta.1 — 2026-09-10
78
+
79
+ ### 추가
80
+
81
+ - **step급 게이트(`agent/pre-step`)**: 피크 시간에 턴 경계에서 중단하는 대신 **다음 step의 모델 요청 전에** 턴을 보류합니다. 세션은 다음 `agent/pre-step`까지 진행하고 거기서 게이트가 닫힙니다(설정 `stepLevelPause`, 기본 on). 오피크에는 **그 자리에서** 재개되며 followup 메시지가 필요 없습니다. 게이트 조건: 피크(북경 시간) + 주말 아님 + `step > 1` + 대상 provider가 공식(`providerGuard`) + 요청급 hold 아님 + 이번 피크 구간에서 스킵 아님. 신규 모듈 `src/step-gate.js`(순수 `decideStepHold` + hold / release / abort / timeout 엔진).
82
+ - **`stepResume` 포트 + RPC + `/resume`**: `sessionGuard.stepResume(sessionId, {bypass})`, `POST /session-guard/rpc {action:'stepResume'}`, `/resume` 모두 게이트를 해제합니다. 수동 재개는 해당 피크 구간 동안 게이트를 중단합니다.
83
+ - **타임아웃 승격**: `stepGateTimeoutMs`(기본 300000)로 게이트를 해제하고 **턴급 force 일시정지로 승격**합니다. 긴 피크에서도 교착이 없고 "5분마다 1 step" 누수도 없습니다.
84
+ - **"⏸ 일시정지" 버튼**(클라이언트, slot `conversation.input.right`, id `session-guard-pause`, order 20 — input-traffic 동결 버튼 왼쪽). 1초마다 `/session-guard/state`를 폴링하며, 미보류 시 비활성, 보류 시 `stepResume`을 호출합니다. 배지는 order 40으로 이동하고 step 보류 수를 표시합니다.
85
+ - **신규 설정**: `stepLevelPause`, `stepGateTimeoutMs`.
86
+ - **신규 상태**: `GET /session-guard/state`가 `paused: { step, turn }`과 `stepGate: { held, since, bypass }`를 반환하고, `/status`는 `stepHeld`, `/diag`는 `stepGate`를 반환합니다. 서비스 포트 `state().paused`는 호환을 위해 불리언 유지(신규 필드 `pausedStep`).
87
+
88
+ ### 수정
89
+
90
+ - **step 보류와 턴급 일시정지의 교착**: `pauseTask` / `resumeTask` / `cancelTask`가 먼저 step 게이트를 해제합니다. step 보류는 `agent/pre-step`에 있어 `assistant/message` / `tool/result`가 영원히 오지 않으므로, `safe` 일시정지가 무한 대기하고 `paused`도 영속화되지 않았습니다.
91
+
92
+ ### 변경
93
+
94
+ - **피크 진입 시 실행 중 턴을 중단하지 않습니다**(`stepLevelPause` on일 때 `onEnterPeak`는 `stopNextTurn` 대신 step 게이트를 arm). off일 때는 기존 턴급 동작 그대로입니다.
95
+ - input-traffic 동결 버튼 라벨이 **"동결 후 추가"**로 바뀌었고(`冻结追加` / `Freeze & append` / `凍結して追加`), 재개 라벨은 **"재개 후 추가"**(`恢复追加` / `Resume & append` / `再開して追加`)입니다 — 턴을 동결하면서 큐를 보존하는 동작으로, 일시정지 버튼과는 다릅니다.
96
+ - **일시정지 버튼이 토글이 되었습니다**: "일시정지" / "재개" (회색 비활성 상태 제거). "일시정지"는 새 `stepPause`를 호출해 **다음 step 경계**에서 세션을 보류합니다(step 1도 대상, 피크/provider 제한 없음). "재개"는 `stepResume`. 신규 포트 메서드 `sessionGuard.stepPause(sessionId)`.
97
+ - **SSE push**: 새 라우트 `GET /session-guard/events?session=<id>`가 step 게이트 상태 변화를 즉시 전달 — 피크에서 자동으로 닫히는 순간 버튼이 "재개"로 바뀝니다. 10초 폴링은 폴백으로 남습니다. `/state`는 `paused.manual`과 `stepGate.manual`을 반환합니다.
98
+ - **스타일을 input-traffic 컴포저 버튼과 맞췄습니다**(높이 24px / 반경 6px / 12px 글꼴 / 동일 border·hover·pressed 토큰). 버튼과 상태 배지 모두. 스타일은 `<style data-plugin-css="session-guard-client">`로 한 번만 주입.
99
+
100
+ ## Unreleased
101
+
102
+ ### 추가
103
+
104
+ - **공식 소스 2차 판정(피크 × 대상 provider)**: 피크 시간에는 대상 라우트가 DeepSeek 공식 소스일 때만 차단하고, 로컬/서드파티 provider는 정상 실행. 판정 순서는 명시 `officialProviders` id 목록 → 실시간 `baseURL` 엔드포인트 → catalog 내장 엔드포인트(pi-ai의 `deepseek`) → 내장 id(`deepseek-official`)이며 `matchedBy`를 반환. 신규 모듈: `src/provider.js`(순수), `src/provider-directory.js`, `src/deferrals.js`, `src/request-guard.js`, `src/targets.js`, `src/wiring.js`.
105
+ - **요청급 백스톱(`agent/request`)**: 피크 진입 후 시작된 세션, 도중에 공식 소스로 전환된 세션을 포착(30s tick은 전환 시점에 `running`이던 세션만 처리). 기본 `hold`는 오류 없이 보류하고 피크 종료 순간 해제(`msUntilOffPeak`); `error`는 식별 가능한 `PEAK_DEFERRED`를 던지고 연기 큐에 기록.
106
+ - **새 설정**: `providerGuard`, `officialProviders`, `officialBaseURLs`, `deferredResume`, `deferredResumeText`, `deferredMode`, `deferredMaxHoldMs`(기본 6h), `guardSubagents`.
107
+ - **새 라우트**: `GET /session-guard/provider?provider=<id>`(판정 진단). `/session-guard/status`가 `providerGuard` / `held` / `deferred` 반환.
108
+ - **드리프트 가드** `tools/check-api-drift.ps1`(4개 tag에서 필수 API 존재 검증).
109
+
110
+ ### 변경
111
+
112
+ - **DSH 이중 버전 지원(0.1.0-rc.7 … 0.1.2-rc.1)**: 하나의 산출물로 `dsh-v0.1.1-rc.2`와 `dsh-v0.1.2-rc.1` 지원.
113
+ - **설정 표면은 교집합 API만**: `settings.register` + `settings.get`. `installSection`(0.1.2+)과 제거된 `installSettingsSection`은 사용하지 않음. 선택적 API는 특성 감지 후 강등.
114
+ - **`src/retry.js`는 정확한 `PEAK_DEFERRED`만 단락**: 429 / `RATE_LIMIT` / `TRANSPORT` / 타임아웃은 여전히 일시적으로 처리. DSH 전역 재시도(`dsh-llm-retry`)는 불변.
115
+ - 배지가 "피크·공식만"과 "피크·전체 정지"를 구분.
116
+
117
+ ## 0.1.4 — 2026-09-09
118
+
119
+ ### 변경
120
+
121
+ - **공개 베타**(`0.1.4-beta.1`): 이중 버전 라인의 베타 채널용으로 버전 표기·README 호환 표·패키지 메타데이터 정비.
122
+
123
+ ## 0.1.1 — 2026-08-24
124
+
125
+ ### 추가
126
+
127
+ - **백엔드 자동 재시도(D9)**: `turn/end` 일시적 실패(error/429/max-tokens)는 적응형 백오프의 `followup(retryText)`로 자동 재개; 영구 실패(인증/잔액/모델/컨텍스트 제한)는 중지; 사용자 개입 또는 성공 턴에서 연속 실패 카운트 리셋.
128
+ - **동결/게이트 양보**: `isFrozen(sessionId)`가 참일 때 재시도 건너뜀, 세션 게이트를 우회하지 않음.
129
+
130
+ ### 변경
131
+
132
+ - `sessionGuard` 중복 포트가 `state(sessionId)`를 노출하여 `{ queueLocked, lockReason, paused, taskControlAvailable, taskControl }` 반환.
133
+ - HTTP 라우트 `GET /session-guard/diag`가 재시도 상태를 포함한 런타임 진단 반환.
134
+
135
+ ### 수정
136
+
137
+ - 주말 감지를 벌거벗은 `getUTCDay()`에서 `Intl.DateTimeFormat`(설정된 타임존 사용)으로 변경, 베이징 타임존 8시간 경계 버그 수정.
138
+
139
+ ## 0.1.0 — 2026-08-18
140
+
141
+ ### 추가
142
+
143
+ - 최초 릴리스: 피크 자동 일시정지(글로벌), 주말 모드, `sessionGuard` 중복 포트 + RPC 브리지 기반 세션별 동결/재개, 커스텀 세션 게이트, 설정 패널.