instar 1.3.468 → 1.3.470
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/dist/commands/init.js +5 -0
- package/dist/commands/init.js.map +1 -1
- package/dist/commands/server.d.ts.map +1 -1
- package/dist/commands/server.js +76 -9
- package/dist/commands/server.js.map +1 -1
- package/dist/config/ConfigDefaults.d.ts.map +1 -1
- package/dist/config/ConfigDefaults.js +40 -0
- package/dist/config/ConfigDefaults.js.map +1 -1
- package/dist/core/CartographerSweepEngine.d.ts +122 -0
- package/dist/core/CartographerSweepEngine.d.ts.map +1 -0
- package/dist/core/CartographerSweepEngine.js +454 -0
- package/dist/core/CartographerSweepEngine.js.map +1 -0
- package/dist/core/CartographerTree.d.ts +95 -0
- package/dist/core/CartographerTree.d.ts.map +1 -1
- package/dist/core/CartographerTree.js +147 -0
- package/dist/core/CartographerTree.js.map +1 -1
- package/dist/core/EscalationGovernor.d.ts +138 -0
- package/dist/core/EscalationGovernor.d.ts.map +1 -0
- package/dist/core/EscalationGovernor.js +308 -0
- package/dist/core/EscalationGovernor.js.map +1 -0
- package/dist/core/IntelligenceRouter.d.ts +7 -0
- package/dist/core/IntelligenceRouter.d.ts.map +1 -1
- package/dist/core/IntelligenceRouter.js +9 -0
- package/dist/core/IntelligenceRouter.js.map +1 -1
- package/dist/core/ModelSwapService.d.ts +116 -0
- package/dist/core/ModelSwapService.d.ts.map +1 -0
- package/dist/core/ModelSwapService.js +266 -0
- package/dist/core/ModelSwapService.js.map +1 -0
- package/dist/core/ModelTierEscalation.d.ts +128 -0
- package/dist/core/ModelTierEscalation.d.ts.map +1 -0
- package/dist/core/ModelTierEscalation.js +232 -0
- package/dist/core/ModelTierEscalation.js.map +1 -0
- package/dist/core/PostUpdateMigrator.d.ts +3 -1
- package/dist/core/PostUpdateMigrator.d.ts.map +1 -1
- package/dist/core/PostUpdateMigrator.js +321 -1
- package/dist/core/PostUpdateMigrator.js.map +1 -1
- package/dist/core/SessionManager.d.ts +5 -0
- package/dist/core/SessionManager.d.ts.map +1 -1
- package/dist/core/SessionManager.js +9 -4
- package/dist/core/SessionManager.js.map +1 -1
- package/dist/core/cartographerSummary.d.ts +62 -0
- package/dist/core/cartographerSummary.d.ts.map +1 -0
- package/dist/core/cartographerSummary.js +0 -0
- package/dist/core/cartographerSummary.js.map +1 -0
- package/dist/core/componentCategories.d.ts.map +1 -1
- package/dist/core/componentCategories.js +7 -0
- package/dist/core/componentCategories.js.map +1 -1
- package/dist/core/types.d.ts +14 -0
- package/dist/core/types.d.ts.map +1 -1
- package/dist/core/types.js.map +1 -1
- package/dist/monitoring/BurnDetector.d.ts +10 -0
- package/dist/monitoring/BurnDetector.d.ts.map +1 -1
- package/dist/monitoring/BurnDetector.js +6 -0
- package/dist/monitoring/BurnDetector.js.map +1 -1
- package/dist/monitoring/CartographerSweepPoller.d.ts +61 -0
- package/dist/monitoring/CartographerSweepPoller.d.ts.map +1 -0
- package/dist/monitoring/CartographerSweepPoller.js +211 -0
- package/dist/monitoring/CartographerSweepPoller.js.map +1 -0
- package/dist/monitoring/GuardPostureTripwire.d.ts +3 -0
- package/dist/monitoring/GuardPostureTripwire.d.ts.map +1 -1
- package/dist/monitoring/GuardPostureTripwire.js +44 -0
- package/dist/monitoring/GuardPostureTripwire.js.map +1 -1
- package/dist/monitoring/HostPressureSampler.d.ts +21 -0
- package/dist/monitoring/HostPressureSampler.d.ts.map +1 -0
- package/dist/monitoring/HostPressureSampler.js +44 -0
- package/dist/monitoring/HostPressureSampler.js.map +1 -0
- package/dist/monitoring/TokenLedger.d.ts +7 -0
- package/dist/monitoring/TokenLedger.d.ts.map +1 -1
- package/dist/monitoring/TokenLedger.js +17 -0
- package/dist/monitoring/TokenLedger.js.map +1 -1
- package/dist/monitoring/UltraSessionCapMonitor.d.ts +61 -0
- package/dist/monitoring/UltraSessionCapMonitor.d.ts.map +1 -0
- package/dist/monitoring/UltraSessionCapMonitor.js +103 -0
- package/dist/monitoring/UltraSessionCapMonitor.js.map +1 -0
- package/dist/scaffold/templates.d.ts.map +1 -1
- package/dist/scaffold/templates.js +4 -0
- package/dist/scaffold/templates.js.map +1 -1
- package/dist/server/AgentServer.d.ts +2 -0
- package/dist/server/AgentServer.d.ts.map +1 -1
- package/dist/server/AgentServer.js +120 -1
- package/dist/server/AgentServer.js.map +1 -1
- package/dist/server/CapabilityIndex.d.ts.map +1 -1
- package/dist/server/CapabilityIndex.js +2 -1
- package/dist/server/CapabilityIndex.js.map +1 -1
- package/dist/server/routes.d.ts +5 -0
- package/dist/server/routes.d.ts.map +1 -1
- package/dist/server/routes.js +152 -7
- package/dist/server/routes.js.map +1 -1
- package/package.json +1 -1
- package/scripts/cartographer-freshness.mjs +209 -0
- package/scripts/lint-no-direct-destructive.js +6 -0
- package/src/data/builtin-manifest.json +83 -67
- package/src/scaffold/templates.ts +4 -0
- package/src/templates/hooks/model-tier-reconciler.js +137 -0
- package/src/templates/hooks/model-tier-skill-entry.sh +72 -0
- package/src/templates/hooks/settings-template.json +15 -0
- package/upgrades/1.3.469.md +71 -0
- package/upgrades/1.3.470.md +27 -0
- package/upgrades/session-mgmt-buildctx-race.eli16.md +9 -0
- package/upgrades/side-effects/cartographer-doc-freshness.md +112 -0
- package/upgrades/side-effects/model-tier-escalation.md +267 -0
- package/upgrades/side-effects/session-mgmt-buildctx-race.md +48 -0
- package/upgrades/side-effects/watchdog-launchctl-test-guard.md +84 -0
- package/upgrades/watchdog-launchctl-test-guard.eli16.md +9 -0
|
@@ -0,0 +1,308 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* EscalationGovernor — §7 (subscription envelope + lease) and §8 (cost
|
|
3
|
+
* guards) of docs/specs/FABLE-MODEL-ESCALATION-SPEC.md.
|
|
4
|
+
*
|
|
5
|
+
* Admission control for model-tier escalation. Every refusal means "the
|
|
6
|
+
* session stays on its default model" — the governor can never block a
|
|
7
|
+
* message, tool call, or session (§3.5).
|
|
8
|
+
*
|
|
9
|
+
* Invariants implemented here:
|
|
10
|
+
* - **Lease, not bare headroom read** (round-1 Adversarial-H2): concurrent
|
|
11
|
+
* escalation onto one account goes through a reservation with
|
|
12
|
+
* `maxConcurrentEscalatedPerAccount`.
|
|
13
|
+
* - **Crash-safe lease** (round-2 Security-N3 / Adversarial-NEW-1): leases
|
|
14
|
+
* carry a TTL, are keyed on the session-instance id (the spawn-generated
|
|
15
|
+
* INSTAR_SESSION_ID — unforgeable from outside, monotonic per spawn), are
|
|
16
|
+
* released on session-end (SessionManager 'sessionReaped' — wired at
|
|
17
|
+
* boot), and a lease whose holder is no longer live is reclaimable.
|
|
18
|
+
* Expiry is evaluated lazily on read — no dedicated poller.
|
|
19
|
+
* - **Quota fail-closed** (round-1 Adversarial-H3): `requireQuotaHeadroom`
|
|
20
|
+
* reads the subscription pool's CACHED snapshot via an injected provider
|
|
21
|
+
* (never a live poll on the hot path); unavailable/errored ⇒ refuse.
|
|
22
|
+
* - **Once-per-episode counting** (round-3 Adversarial-NEW-5): an
|
|
23
|
+
* escalation counts against `maxEscalationsPerHour` exactly once per
|
|
24
|
+
* (instance-id, tier-transition) episode; canary retries and per-turn
|
|
25
|
+
* re-derivations never multiply the count. **Accounting fails toward
|
|
26
|
+
* counting** (round-2 Adversarial-NEW-2): `recordInjection` is called at
|
|
27
|
+
* injection time, regardless of read-back outcome.
|
|
28
|
+
* - **Free windows** (§8): UTC-date, inclusive through the named day;
|
|
29
|
+
* informational only — crossing the expiry emits ONE audit note (no
|
|
30
|
+
* silent cost cliff). The window relaxes nothing structural.
|
|
31
|
+
* - **Daily ultra-token cap as admission control** (§8): refuses NEW
|
|
32
|
+
* escalations once today's ultra spend (injected provider) crosses the
|
|
33
|
+
* cap. Mid-run visibility is UltraSessionCapMonitor's job.
|
|
34
|
+
*
|
|
35
|
+
* State is file-backed under `<stateDir>/state/model-tier-escalation/`
|
|
36
|
+
* (atomic tmp+rename writes; single-writer — the server process). The
|
|
37
|
+
* audit trail is an append-only JSONL with structured fields only — never
|
|
38
|
+
* raw operator text (round-2 Security-F7).
|
|
39
|
+
*/
|
|
40
|
+
import * as fs from 'node:fs';
|
|
41
|
+
import * as path from 'node:path';
|
|
42
|
+
import { isWithinFreeWindow, } from './ModelTierEscalation.js';
|
|
43
|
+
/** Conservative "has headroom" bound: a cached window utilization at/over
|
|
44
|
+
* this percentage is treated as capped for escalation purposes. */
|
|
45
|
+
export const QUOTA_HEADROOM_MAX_UTILIZATION_PCT = 90;
|
|
46
|
+
const EPISODE_RETENTION_MS = 24 * 60 * 60 * 1000;
|
|
47
|
+
export class EscalationGovernor {
|
|
48
|
+
deps;
|
|
49
|
+
dir;
|
|
50
|
+
statePath;
|
|
51
|
+
auditPath;
|
|
52
|
+
now;
|
|
53
|
+
constructor(deps) {
|
|
54
|
+
this.deps = deps;
|
|
55
|
+
this.dir = path.join(deps.stateDir, 'state', 'model-tier-escalation');
|
|
56
|
+
this.statePath = path.join(this.dir, 'governor.json');
|
|
57
|
+
this.auditPath = path.join(this.dir, 'audit.jsonl');
|
|
58
|
+
this.now = deps.now ?? (() => Date.now());
|
|
59
|
+
}
|
|
60
|
+
/**
|
|
61
|
+
* §7/§8 admission decision for escalating `instanceId` on `accountId`.
|
|
62
|
+
* Pure cost/capacity routing — a refusal means "stay on default".
|
|
63
|
+
* Acquiring is idempotent: an instance already holding a lease is
|
|
64
|
+
* re-admitted without consuming additional capacity.
|
|
65
|
+
*/
|
|
66
|
+
admitEscalation(input) {
|
|
67
|
+
const cfg = this.deps.getConfig();
|
|
68
|
+
if (!cfg.enabled) {
|
|
69
|
+
return this.refuse(input, 'disabled');
|
|
70
|
+
}
|
|
71
|
+
if (!input.instanceId) {
|
|
72
|
+
return this.refuse(input, 'no-instance-id');
|
|
73
|
+
}
|
|
74
|
+
const accountId = input.accountId ?? 'default';
|
|
75
|
+
const state = this.loadState();
|
|
76
|
+
this.reclaimStale(state);
|
|
77
|
+
const guards = cfg.costGuards;
|
|
78
|
+
// Free-window bookkeeping (informational; never gates) — §8 "no silent
|
|
79
|
+
// cost cliff": the first admission attempt after a window expires emits
|
|
80
|
+
// one audit note.
|
|
81
|
+
const freeWindow = isWithinFreeWindow(input.modelId, guards, this.now());
|
|
82
|
+
this.noteFreeWindowExpiryOnce(state, input.modelId, guards, freeWindow);
|
|
83
|
+
// 1) Lease capacity (per-account, idempotent for the same instance).
|
|
84
|
+
const holding = state.leases.find(l => l.instanceId === input.instanceId);
|
|
85
|
+
if (!holding) {
|
|
86
|
+
const accountLeases = state.leases.filter(l => l.accountId === accountId);
|
|
87
|
+
if (accountLeases.length >= guards.maxConcurrentEscalatedPerAccount) {
|
|
88
|
+
this.saveState(state); // persist any reclaim/expiry-note work
|
|
89
|
+
return this.refuse(input, 'lease-capacity');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
// 2) Hourly escalation budget (§8 — load-bearing for Trigger #1).
|
|
93
|
+
// The episode for THIS (instance, transition) does not double-count.
|
|
94
|
+
const episodeKey = this.episodeKey(input.instanceId, input.transition);
|
|
95
|
+
const hourAgo = this.now() - 3_600_000;
|
|
96
|
+
const countedThisHour = Object.entries(state.episodes).filter(([key, at]) => at >= hourAgo && key !== episodeKey).length;
|
|
97
|
+
const alreadyCounted = Object.prototype.hasOwnProperty.call(state.episodes, episodeKey);
|
|
98
|
+
if (!alreadyCounted && countedThisHour >= guards.maxEscalationsPerHour) {
|
|
99
|
+
this.saveState(state);
|
|
100
|
+
return this.refuse(input, 'hourly-budget-exhausted');
|
|
101
|
+
}
|
|
102
|
+
// 3) Quota headroom from the CACHED snapshot — unavailable ⇒ fail closed.
|
|
103
|
+
if (guards.requireQuotaHeadroom) {
|
|
104
|
+
let snapshot = null;
|
|
105
|
+
try {
|
|
106
|
+
snapshot = this.deps.quotaSnapshot?.(accountId) ?? null;
|
|
107
|
+
}
|
|
108
|
+
catch {
|
|
109
|
+
// @silent-fallback-ok — fail-closed conversion, not a swallow: an
|
|
110
|
+
// erroring probe reads as "unavailable" and the very next branch
|
|
111
|
+
// refuses with the AUDITED structured reason 'quota-unavailable'.
|
|
112
|
+
snapshot = null;
|
|
113
|
+
}
|
|
114
|
+
if (!snapshot) {
|
|
115
|
+
this.saveState(state);
|
|
116
|
+
return this.refuse(input, 'quota-unavailable');
|
|
117
|
+
}
|
|
118
|
+
const capped = [snapshot.fiveHour, snapshot.sevenDay].some(w => w && w.utilizationPct >= QUOTA_HEADROOM_MAX_UTILIZATION_PCT);
|
|
119
|
+
if (capped) {
|
|
120
|
+
this.saveState(state);
|
|
121
|
+
return this.refuse(input, 'quota-capped');
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
// 4) Daily ultra-token cap as ADMISSION control (§8). Cap configured but
|
|
125
|
+
// spend unreadable ⇒ fail closed.
|
|
126
|
+
if (guards.dailyUltraTokenCap != null) {
|
|
127
|
+
let spent = null;
|
|
128
|
+
try {
|
|
129
|
+
spent = this.deps.ultraTokensTodayUtc?.() ?? null;
|
|
130
|
+
}
|
|
131
|
+
catch {
|
|
132
|
+
// @silent-fallback-ok — fail-closed conversion, not a swallow: an
|
|
133
|
+
// unreadable ledger reads as null and the next branch refuses with
|
|
134
|
+
// the AUDITED structured reason 'daily-cap-exhausted'.
|
|
135
|
+
spent = null;
|
|
136
|
+
}
|
|
137
|
+
if (spent == null || spent >= guards.dailyUltraTokenCap) {
|
|
138
|
+
this.saveState(state);
|
|
139
|
+
return this.refuse(input, 'daily-cap-exhausted');
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (input.dry) {
|
|
143
|
+
this.saveState(state); // persist reclaim/expiry-note work only
|
|
144
|
+
this.audit({
|
|
145
|
+
type: 'dry-admit',
|
|
146
|
+
instanceId: input.instanceId,
|
|
147
|
+
accountId,
|
|
148
|
+
modelId: input.modelId,
|
|
149
|
+
transition: input.transition,
|
|
150
|
+
freeWindow,
|
|
151
|
+
});
|
|
152
|
+
return { allow: true, freeWindow };
|
|
153
|
+
}
|
|
154
|
+
// Admit: acquire/refresh the lease (TTL = maxEscalationTtlMs).
|
|
155
|
+
const lease = {
|
|
156
|
+
instanceId: input.instanceId,
|
|
157
|
+
accountId,
|
|
158
|
+
acquiredAt: this.now(),
|
|
159
|
+
ttlMs: guards.maxEscalationTtlMs,
|
|
160
|
+
};
|
|
161
|
+
state.leases = state.leases.filter(l => l.instanceId !== input.instanceId);
|
|
162
|
+
state.leases.push(lease);
|
|
163
|
+
this.saveState(state);
|
|
164
|
+
this.audit({
|
|
165
|
+
type: 'admit',
|
|
166
|
+
instanceId: input.instanceId,
|
|
167
|
+
accountId,
|
|
168
|
+
modelId: input.modelId,
|
|
169
|
+
transition: input.transition,
|
|
170
|
+
freeWindow,
|
|
171
|
+
});
|
|
172
|
+
return { allow: true, freeWindow };
|
|
173
|
+
}
|
|
174
|
+
/**
|
|
175
|
+
* Count the escalation against the hourly budget — called AT INJECTION
|
|
176
|
+
* time (fails toward counting, round-2 Adversarial-NEW-2), idempotent per
|
|
177
|
+
* (instance, transition) episode (round-3 Adversarial-NEW-5).
|
|
178
|
+
* Returns true when this call newly counted the episode.
|
|
179
|
+
*/
|
|
180
|
+
recordInjection(instanceId, transition) {
|
|
181
|
+
const state = this.loadState();
|
|
182
|
+
const key = this.episodeKey(instanceId, transition);
|
|
183
|
+
if (Object.prototype.hasOwnProperty.call(state.episodes, key)) {
|
|
184
|
+
return false; // already counted this episode — retries don't multiply
|
|
185
|
+
}
|
|
186
|
+
state.episodes[key] = this.now();
|
|
187
|
+
this.saveState(state);
|
|
188
|
+
this.audit({ type: 'injection-counted', instanceId, transition });
|
|
189
|
+
return true;
|
|
190
|
+
}
|
|
191
|
+
/** Release the instance's lease (wired to SessionManager 'sessionReaped'
|
|
192
|
+
* at boot — the same close event that retires the session, §7). */
|
|
193
|
+
releaseLease(instanceId) {
|
|
194
|
+
const state = this.loadState();
|
|
195
|
+
const before = state.leases.length;
|
|
196
|
+
state.leases = state.leases.filter(l => l.instanceId !== instanceId);
|
|
197
|
+
if (state.leases.length !== before) {
|
|
198
|
+
this.saveState(state);
|
|
199
|
+
this.audit({ type: 'lease-released', instanceId });
|
|
200
|
+
}
|
|
201
|
+
}
|
|
202
|
+
/** Current live leases (post-reclaim) — observability/testing surface. */
|
|
203
|
+
activeLeases() {
|
|
204
|
+
const state = this.loadState();
|
|
205
|
+
const changed = this.reclaimStale(state);
|
|
206
|
+
if (changed)
|
|
207
|
+
this.saveState(state);
|
|
208
|
+
return [...state.leases];
|
|
209
|
+
}
|
|
210
|
+
// ── internals ──────────────────────────────────────────────────────────
|
|
211
|
+
episodeKey(instanceId, transition) {
|
|
212
|
+
return `${instanceId}::${transition}`;
|
|
213
|
+
}
|
|
214
|
+
/** Drop expired leases and leases whose holder is no longer live. Lazy —
|
|
215
|
+
* runs on every read; no poller (§7). Returns true when anything changed. */
|
|
216
|
+
reclaimStale(state) {
|
|
217
|
+
const now = this.now();
|
|
218
|
+
const before = state.leases.length;
|
|
219
|
+
state.leases = state.leases.filter(l => {
|
|
220
|
+
if (now - l.acquiredAt >= l.ttlMs) {
|
|
221
|
+
this.audit({ type: 'lease-reclaimed', instanceId: l.instanceId, why: 'ttl-expired' });
|
|
222
|
+
return false;
|
|
223
|
+
}
|
|
224
|
+
try {
|
|
225
|
+
if (this.deps.isHolderLive && !this.deps.isHolderLive(l.instanceId)) {
|
|
226
|
+
this.audit({ type: 'lease-reclaimed', instanceId: l.instanceId, why: 'holder-not-live' });
|
|
227
|
+
return false;
|
|
228
|
+
}
|
|
229
|
+
}
|
|
230
|
+
catch {
|
|
231
|
+
// liveness probe errored — keep the lease (TTL still bounds it)
|
|
232
|
+
}
|
|
233
|
+
return true;
|
|
234
|
+
});
|
|
235
|
+
// Prune stale episodes while we're here (same lazy pass).
|
|
236
|
+
for (const [key, at] of Object.entries(state.episodes)) {
|
|
237
|
+
if (now - at > EPISODE_RETENTION_MS)
|
|
238
|
+
delete state.episodes[key];
|
|
239
|
+
}
|
|
240
|
+
return state.leases.length !== before;
|
|
241
|
+
}
|
|
242
|
+
noteFreeWindowExpiryOnce(state, modelId, guards, currentlyInWindow) {
|
|
243
|
+
const windows = guards.respectFreeWindows ?? {};
|
|
244
|
+
if (!Object.prototype.hasOwnProperty.call(windows, modelId))
|
|
245
|
+
return;
|
|
246
|
+
if (currentlyInWindow)
|
|
247
|
+
return;
|
|
248
|
+
if (state.freeWindowExpiryNoted[modelId] === windows[modelId])
|
|
249
|
+
return;
|
|
250
|
+
state.freeWindowExpiryNoted[modelId] = windows[modelId];
|
|
251
|
+
this.audit({
|
|
252
|
+
type: 'free-window-expired',
|
|
253
|
+
modelId,
|
|
254
|
+
window: windows[modelId],
|
|
255
|
+
note: 'free window crossed — quota/budget guards apply unchanged',
|
|
256
|
+
});
|
|
257
|
+
}
|
|
258
|
+
loadState() {
|
|
259
|
+
try {
|
|
260
|
+
const raw = JSON.parse(fs.readFileSync(this.statePath, 'utf-8'));
|
|
261
|
+
return {
|
|
262
|
+
leases: Array.isArray(raw.leases) ? raw.leases.filter(l => l && typeof l.instanceId === 'string') : [],
|
|
263
|
+
episodes: raw.episodes && typeof raw.episodes === 'object' ? raw.episodes : {},
|
|
264
|
+
freeWindowExpiryNoted: raw.freeWindowExpiryNoted && typeof raw.freeWindowExpiryNoted === 'object'
|
|
265
|
+
? raw.freeWindowExpiryNoted
|
|
266
|
+
: {},
|
|
267
|
+
};
|
|
268
|
+
}
|
|
269
|
+
catch {
|
|
270
|
+
return { leases: [], episodes: {}, freeWindowExpiryNoted: {} };
|
|
271
|
+
}
|
|
272
|
+
}
|
|
273
|
+
saveState(state) {
|
|
274
|
+
try {
|
|
275
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
276
|
+
const tmp = `${this.statePath}.tmp`;
|
|
277
|
+
fs.writeFileSync(tmp, JSON.stringify(state, null, 2));
|
|
278
|
+
fs.renameSync(tmp, this.statePath);
|
|
279
|
+
}
|
|
280
|
+
catch (err) {
|
|
281
|
+
// State-write failure must never block the caller — but it must be
|
|
282
|
+
// loud: a governor that can't persist is a governor that can't bound.
|
|
283
|
+
console.warn(`[escalation-governor] state write failed: ${err.message}`);
|
|
284
|
+
}
|
|
285
|
+
}
|
|
286
|
+
/** Structured-fields-only audit appender (Sec-F7: no raw operator text). */
|
|
287
|
+
audit(event) {
|
|
288
|
+
try {
|
|
289
|
+
fs.mkdirSync(this.dir, { recursive: true });
|
|
290
|
+
fs.appendFileSync(this.auditPath, JSON.stringify({ ts: new Date(this.now()).toISOString(), ...event }) + '\n');
|
|
291
|
+
}
|
|
292
|
+
catch {
|
|
293
|
+
// best-effort — never throws into the routing path
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
refuse(input, reason) {
|
|
297
|
+
this.audit({
|
|
298
|
+
type: 'refuse',
|
|
299
|
+
reason,
|
|
300
|
+
instanceId: input.instanceId,
|
|
301
|
+
accountId: input.accountId ?? 'default',
|
|
302
|
+
modelId: input.modelId,
|
|
303
|
+
transition: input.transition,
|
|
304
|
+
});
|
|
305
|
+
return { allow: false, reason };
|
|
306
|
+
}
|
|
307
|
+
}
|
|
308
|
+
//# sourceMappingURL=EscalationGovernor.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"EscalationGovernor.js","sourceRoot":"","sources":["../../src/core/EscalationGovernor.ts"],"names":[],"mappings":"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"}
|
|
@@ -75,6 +75,13 @@ export declare class IntelligenceRouter implements IntelligenceProvider {
|
|
|
75
75
|
private readonly opts;
|
|
76
76
|
private readonly cache;
|
|
77
77
|
constructor(opts: IntelligenceRouterOptions);
|
|
78
|
+
/**
|
|
79
|
+
* The framework the default (shared, global-breaker) provider speaks — i.e. the
|
|
80
|
+
* framework a component routes to when nothing routes it elsewhere. The
|
|
81
|
+
* CartographerSweep off-Claude probe compares `for(...).framework` against this
|
|
82
|
+
* to detect a silent resolve-to-default (Claude) and refuse to author there.
|
|
83
|
+
*/
|
|
84
|
+
get defaultFramework(): IntelligenceFramework;
|
|
78
85
|
/** Resolve the framework for a component+category against a config (pure). */
|
|
79
86
|
resolveFramework(component: string | undefined, category: ComponentCategory, cfg: ComponentFrameworksConfig | undefined): IntelligenceFramework;
|
|
80
87
|
/**
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntelligenceRouter.d.ts","sourceRoot":"","sources":["../../src/core/IntelligenceRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,yBAAyB;IACxC,iGAAiG;IACjG,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACvE,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAClD,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,EAAE,EAAE,qBAAqB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,6HAA6H;IAC7H,eAAe,EAAE,oBAAoB,CAAC;IACtC,8CAA8C;IAC9C,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,sHAAsH;IACtH,aAAa,EAAE,MAAM,yBAAyB,GAAG,SAAS,CAAC;IAC3D;;;;OAIG;IACH,aAAa,EAAE,CAAC,SAAS,EAAE,qBAAqB,KAAK,oBAAoB,GAAG,IAAI,CAAC;IACjF,wGAAwG;IACxG,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC/C;AAMD,qBAAa,kBAAmB,YAAW,oBAAoB;IAGjD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqD;gBAE9C,IAAI,EAAE,yBAAyB;IAE5D,8EAA8E;IAC9E,gBAAgB,CACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,EAAE,yBAAyB,GAAG,SAAS,GACzC,qBAAqB;IAQxB;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,iBAAiB,GAAG;QAC5D,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,SAAS,EAAE,qBAAqB,CAAC;QACjC,SAAS,EAAE,OAAO,CAAC;KACpB;IAQD,+FAA+F;IAC/F,OAAO,CAAC,WAAW;IAcnB,4GAA4G;IAC5G,OAAO,CAAC,eAAe;IAIjB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;CAoE/E"}
|
|
1
|
+
{"version":3,"file":"IntelligenceRouter.d.ts","sourceRoot":"","sources":["../../src/core/IntelligenceRouter.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;GAwBG;AAEH,OAAO,KAAK,EAAE,oBAAoB,EAAE,mBAAmB,EAAE,MAAM,YAAY,CAAC;AAC5E,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,kCAAkC,CAAC;AAC9E,OAAO,EACL,KAAK,iBAAiB,EAGvB,MAAM,0BAA0B,CAAC;AAElC,MAAM,WAAW,yBAAyB;IACxC,iGAAiG;IACjG,OAAO,CAAC,EAAE,qBAAqB,CAAC;IAChC,8DAA8D;IAC9D,UAAU,CAAC,EAAE,OAAO,CAAC,MAAM,CAAC,iBAAiB,EAAE,qBAAqB,CAAC,CAAC,CAAC;IACvE,uDAAuD;IACvD,SAAS,CAAC,EAAE,MAAM,CAAC,MAAM,EAAE,qBAAqB,CAAC,CAAC;IAClD,6GAA6G;IAC7G,QAAQ,CAAC,EAAE,SAAS,GAAG,MAAM,CAAC;IAC9B;;;;;;;;;;OAUG;IACH,WAAW,CAAC,EAAE,qBAAqB,EAAE,CAAC;CACvC;AAED,MAAM,WAAW,iBAAiB;IAChC,SAAS,EAAE,MAAM,CAAC;IAClB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,IAAI,EAAE,qBAAqB,CAAC;IAC5B,EAAE,EAAE,qBAAqB,CAAC;IAC1B,MAAM,EAAE,MAAM,CAAC;CAChB;AAED,MAAM,WAAW,yBAAyB;IACxC,6HAA6H;IAC7H,eAAe,EAAE,oBAAoB,CAAC;IACtC,8CAA8C;IAC9C,gBAAgB,EAAE,qBAAqB,CAAC;IACxC,sHAAsH;IACtH,aAAa,EAAE,MAAM,yBAAyB,GAAG,SAAS,CAAC;IAC3D;;;;OAIG;IACH,aAAa,EAAE,CAAC,SAAS,EAAE,qBAAqB,KAAK,oBAAoB,GAAG,IAAI,CAAC;IACjF,wGAAwG;IACxG,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,IAAI,CAAC;CAC/C;AAMD,qBAAa,kBAAmB,YAAW,oBAAoB;IAGjD,OAAO,CAAC,QAAQ,CAAC,IAAI;IAFjC,OAAO,CAAC,QAAQ,CAAC,KAAK,CAAqD;gBAE9C,IAAI,EAAE,yBAAyB;IAE5D;;;;;OAKG;IACH,IAAI,gBAAgB,IAAI,qBAAqB,CAE5C;IAED,8EAA8E;IAC9E,gBAAgB,CACd,SAAS,EAAE,MAAM,GAAG,SAAS,EAC7B,QAAQ,EAAE,iBAAiB,EAC3B,GAAG,EAAE,yBAAyB,GAAG,SAAS,GACzC,qBAAqB;IAQxB;;;OAGG;IACH,GAAG,CAAC,SAAS,EAAE,MAAM,EAAE,gBAAgB,CAAC,EAAE,iBAAiB,GAAG;QAC5D,SAAS,EAAE,MAAM,CAAC;QAClB,QAAQ,EAAE,iBAAiB,CAAC;QAC5B,SAAS,EAAE,qBAAqB,CAAC;QACjC,SAAS,EAAE,OAAO,CAAC;KACpB;IAQD,+FAA+F;IAC/F,OAAO,CAAC,WAAW;IAcnB,4GAA4G;IAC5G,OAAO,CAAC,eAAe;IAIjB,QAAQ,CAAC,MAAM,EAAE,MAAM,EAAE,OAAO,CAAC,EAAE,mBAAmB,GAAG,OAAO,CAAC,MAAM,CAAC;CAoE/E"}
|
|
@@ -30,6 +30,15 @@ export class IntelligenceRouter {
|
|
|
30
30
|
constructor(opts) {
|
|
31
31
|
this.opts = opts;
|
|
32
32
|
}
|
|
33
|
+
/**
|
|
34
|
+
* The framework the default (shared, global-breaker) provider speaks — i.e. the
|
|
35
|
+
* framework a component routes to when nothing routes it elsewhere. The
|
|
36
|
+
* CartographerSweep off-Claude probe compares `for(...).framework` against this
|
|
37
|
+
* to detect a silent resolve-to-default (Claude) and refuse to author there.
|
|
38
|
+
*/
|
|
39
|
+
get defaultFramework() {
|
|
40
|
+
return this.opts.defaultFramework;
|
|
41
|
+
}
|
|
33
42
|
/** Resolve the framework for a component+category against a config (pure). */
|
|
34
43
|
resolveFramework(component, category, cfg) {
|
|
35
44
|
if (!cfg)
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"IntelligenceRouter.js","sourceRoot":"","sources":["../../src/core/IntelligenceRouter.ts"],"names":[],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"IntelligenceRouter.js","sourceRoot":"","sources":["../../src/core/IntelligenceRouter.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,116 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* ModelSwapService — §5.3 of docs/specs/FABLE-MODEL-ESCALATION-SPEC.md.
|
|
3
|
+
*
|
|
4
|
+
* The narrow, server-side mid-session model swap (Trigger #1 only). The
|
|
5
|
+
* reconciler hook only SIGNALS — this service is the single authority that
|
|
6
|
+
* performs a swap, and it verifies every swap with an independent oracle.
|
|
7
|
+
*
|
|
8
|
+
* Contract (each clause spec-cited):
|
|
9
|
+
* - `:name` resolves by EXACT match against the live session registry —
|
|
10
|
+
* never globbed, substring-matched, or concatenated into the tmux target
|
|
11
|
+
* (round-2 Security-N1). The only string ever sent to the pane is the
|
|
12
|
+
* server-derived `/model <validated-id>`.
|
|
13
|
+
* - The model id is derived server-side via the §5.1 resolver — NEVER
|
|
14
|
+
* accepted from the caller (Sec-F5).
|
|
15
|
+
* - Refuses protected sessions (authorization boundary) and sessions that
|
|
16
|
+
* are not idle-with-empty-input (round-2 Security-F6 live-input
|
|
17
|
+
* collision window).
|
|
18
|
+
* - Honors `enabled:false` / `dryRun:true`; dryRun evaluates every gate
|
|
19
|
+
* but acquires nothing and injects nothing.
|
|
20
|
+
* - Injects via tmux `send-keys -l --` + a SEPARATE Enter (SessionManager
|
|
21
|
+
* .sendInput — the same hardened primitive the input route uses).
|
|
22
|
+
* - **Canary read-back via an oracle independent of the Session.model
|
|
23
|
+
* field this swap would write** (round-3 Integration-NEW-1): the pane's
|
|
24
|
+
* own acknowledgment of the /model command, parsed to exclude the echo
|
|
25
|
+
* of our injected input. Only on a confirmed match is Session.model
|
|
26
|
+
* updated. Unconfirmed ⇒ Session.model untouched, behaviourally default,
|
|
27
|
+
* ONE Attention item (round-1 Adversarial-H5 / Lessons-C3).
|
|
28
|
+
* - **Accounting fails toward counting** (round-2 Adversarial-NEW-2): the
|
|
29
|
+
* escalation is counted at injection, before the canary, once per
|
|
30
|
+
* (instance, transition) episode.
|
|
31
|
+
* - Server-side dwell guard: never swaps the same session twice within
|
|
32
|
+
* `minTierDwellMs` (§5.5 hysteresis backstop; suppressed flaps audited).
|
|
33
|
+
*/
|
|
34
|
+
import type { Session } from './types.js';
|
|
35
|
+
import { type EscalationTier, type TierEscalationConfig } from './ModelTierEscalation.js';
|
|
36
|
+
import type { EscalationGovernor } from './EscalationGovernor.js';
|
|
37
|
+
/** The narrow SessionManager surface the swap service is allowed to touch. */
|
|
38
|
+
export interface SwapSessionFacade {
|
|
39
|
+
listRunningSessions(): Session[];
|
|
40
|
+
captureMeaningfulTail(tmuxSession: string, lines: number): string | null;
|
|
41
|
+
sendInput(tmuxSession: string, input: string): boolean;
|
|
42
|
+
}
|
|
43
|
+
export interface AttentionItemLike {
|
|
44
|
+
id: string;
|
|
45
|
+
title: string;
|
|
46
|
+
summary: string;
|
|
47
|
+
category: string;
|
|
48
|
+
priority: 'URGENT' | 'HIGH' | 'NORMAL' | 'LOW';
|
|
49
|
+
}
|
|
50
|
+
export interface ModelSwapServiceDeps {
|
|
51
|
+
stateDir: string;
|
|
52
|
+
sessions: SwapSessionFacade;
|
|
53
|
+
/** Persist a mutated Session record (StateManager.saveSession). */
|
|
54
|
+
saveSession: (session: Session) => void;
|
|
55
|
+
protectedSessions: () => string[];
|
|
56
|
+
getConfig: () => TierEscalationConfig;
|
|
57
|
+
governor: Pick<EscalationGovernor, 'admitEscalation' | 'recordInjection'>;
|
|
58
|
+
/** Raise an Attention item (TelegramAdapter.createAttentionItem). Optional —
|
|
59
|
+
* absence degrades to audit-only, never throws. */
|
|
60
|
+
attention?: (item: AttentionItemLike) => unknown;
|
|
61
|
+
/** Canary attempts/cadence — injectable for tests. */
|
|
62
|
+
canaryAttempts?: number;
|
|
63
|
+
canaryIntervalMs?: number;
|
|
64
|
+
wait?: (ms: number) => Promise<void>;
|
|
65
|
+
now?: () => number;
|
|
66
|
+
}
|
|
67
|
+
export type SwapStatus = 'swapped' | 'unconfirmed' | 'dry-run' | 'noop' | 'refused';
|
|
68
|
+
export interface SwapResult {
|
|
69
|
+
status: SwapStatus;
|
|
70
|
+
reason?: string;
|
|
71
|
+
/** The server-derived target model id (when one resolved). */
|
|
72
|
+
model?: string;
|
|
73
|
+
/** True only when the independent oracle confirmed the live model. */
|
|
74
|
+
confirmed?: boolean;
|
|
75
|
+
}
|
|
76
|
+
/**
|
|
77
|
+
* Does the pane tail show a prompt-ready idle state WITH an empty input
|
|
78
|
+
* line? Fail-closed: anything ambiguous returns false and the swap is
|
|
79
|
+
* refused as retryable (round-2 Security-F6).
|
|
80
|
+
*/
|
|
81
|
+
export declare function paneIdleWithEmptyInput(tail: string | null): boolean;
|
|
82
|
+
/**
|
|
83
|
+
* Independent-oracle parse (§5.3 canary): does the pane acknowledge that
|
|
84
|
+
* the model is now `modelId`, on a line that is NOT the echo of our own
|
|
85
|
+
* injected `/model …` input? Conservative by design: an unrecognized format
|
|
86
|
+
* reads as NOT confirmed (the spec's honest-degrade direction).
|
|
87
|
+
*
|
|
88
|
+
* The REAL CLI acks with the model's DISPLAY NAME, not the id (live-canary
|
|
89
|
+
* finding, 2026-06-09): `/model claude-fable-5` → "Set model to Fable 5 and
|
|
90
|
+
* saved as your default for new sessions". We accept the exact id OR the
|
|
91
|
+
* display form derived from the id (closed-enum ids only ever reach here,
|
|
92
|
+
* so the derivation is over a known, validated vocabulary): family token
|
|
93
|
+
* capitalized + up to two leading version components dot-joined —
|
|
94
|
+
* claude-fable-5 → "Fable 5", claude-opus-4-8 → "Opus 4.8".
|
|
95
|
+
*/
|
|
96
|
+
export declare function paneConfirmsModel(tail: string | null, modelId: string): boolean;
|
|
97
|
+
export declare class ModelSwapService {
|
|
98
|
+
private readonly deps;
|
|
99
|
+
private readonly auditPath;
|
|
100
|
+
private readonly now;
|
|
101
|
+
private readonly wait;
|
|
102
|
+
/** In-memory per-session last-swap timestamps (dwell backstop). Reset on
|
|
103
|
+
* restart — the safe direction (a restart may swap immediately). */
|
|
104
|
+
private readonly lastSwapAt;
|
|
105
|
+
constructor(deps: ModelSwapServiceDeps);
|
|
106
|
+
/**
|
|
107
|
+
* Swap `name`'s session to `tier`. Body-validated upstream; this method
|
|
108
|
+
* re-validates everything it relies on (defense in depth).
|
|
109
|
+
*/
|
|
110
|
+
swap(name: string, tier: EscalationTier): Promise<SwapResult>;
|
|
111
|
+
private refuse;
|
|
112
|
+
/** Structured-fields-only audit appender (Sec-F7) — same trail as the
|
|
113
|
+
* governor so one file tells the whole escalation story. */
|
|
114
|
+
private audit;
|
|
115
|
+
}
|
|
116
|
+
//# sourceMappingURL=ModelSwapService.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"ModelSwapService.d.ts","sourceRoot":"","sources":["../../src/core/ModelSwapService.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;GAgCG;AAIH,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,YAAY,CAAC;AAE1C,OAAO,EAKL,KAAK,cAAc,EACnB,KAAK,oBAAoB,EAC1B,MAAM,0BAA0B,CAAC;AAClC,OAAO,KAAK,EAAe,kBAAkB,EAAE,MAAM,yBAAyB,CAAC;AAE/E,8EAA8E;AAC9E,MAAM,WAAW,iBAAiB;IAChC,mBAAmB,IAAI,OAAO,EAAE,CAAC;IACjC,qBAAqB,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,MAAM,GAAG,IAAI,CAAC;IACzE,SAAS,CAAC,WAAW,EAAE,MAAM,EAAE,KAAK,EAAE,MAAM,GAAG,OAAO,CAAC;CACxD;AAED,MAAM,WAAW,iBAAiB;IAChC,EAAE,EAAE,MAAM,CAAC;IACX,KAAK,EAAE,MAAM,CAAC;IACd,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,QAAQ,GAAG,MAAM,GAAG,QAAQ,GAAG,KAAK,CAAC;CAChD;AAED,MAAM,WAAW,oBAAoB;IACnC,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,iBAAiB,CAAC;IAC5B,mEAAmE;IACnE,WAAW,EAAE,CAAC,OAAO,EAAE,OAAO,KAAK,IAAI,CAAC;IACxC,iBAAiB,EAAE,MAAM,MAAM,EAAE,CAAC;IAClC,SAAS,EAAE,MAAM,oBAAoB,CAAC;IACtC,QAAQ,EAAE,IAAI,CAAC,kBAAkB,EAAE,iBAAiB,GAAG,iBAAiB,CAAC,CAAC;IAC1E;wDACoD;IACpD,SAAS,CAAC,EAAE,CAAC,IAAI,EAAE,iBAAiB,KAAK,OAAO,CAAC;IACjD,sDAAsD;IACtD,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,IAAI,CAAC,EAAE,CAAC,EAAE,EAAE,MAAM,KAAK,OAAO,CAAC,IAAI,CAAC,CAAC;IACrC,GAAG,CAAC,EAAE,MAAM,MAAM,CAAC;CACpB;AAED,MAAM,MAAM,UAAU,GAClB,SAAS,GACT,aAAa,GACb,SAAS,GACT,MAAM,GACN,SAAS,CAAC;AAEd,MAAM,WAAW,UAAU;IACzB,MAAM,EAAE,UAAU,CAAC;IACnB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,8DAA8D;IAC9D,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,sEAAsE;IACtE,SAAS,CAAC,EAAE,OAAO,CAAC;CACrB;AAED;;;;GAIG;AACH,wBAAgB,sBAAsB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,GAAG,OAAO,CAiBnE;AAED;;;;;;;;;;;;;GAaG;AACH,wBAAgB,iBAAiB,CAAC,IAAI,EAAE,MAAM,GAAG,IAAI,EAAE,OAAO,EAAE,MAAM,GAAG,OAAO,CAe/E;AAED,qBAAa,gBAAgB;IAC3B,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAuB;IAC5C,OAAO,CAAC,QAAQ,CAAC,SAAS,CAAS;IACnC,OAAO,CAAC,QAAQ,CAAC,GAAG,CAAe;IACnC,OAAO,CAAC,QAAQ,CAAC,IAAI,CAAgC;IACrD;yEACqE;IACrE,OAAO,CAAC,QAAQ,CAAC,UAAU,CAA6B;gBAE5C,IAAI,EAAE,oBAAoB;IAOtC;;;OAGG;IACG,IAAI,CAAC,IAAI,EAAE,MAAM,EAAE,IAAI,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IA0JnE,OAAO,CAAC,MAAM;IAKd;iEAC6D;IAC7D,OAAO,CAAC,KAAK;CAWd"}
|