principles-disciple 1.7.6 → 1.7.8
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/context.js +5 -15
- package/dist/commands/evolution-status.js +2 -9
- package/dist/commands/export.js +61 -8
- package/dist/commands/nocturnal-review.d.ts +24 -0
- package/dist/commands/nocturnal-review.js +265 -0
- package/dist/commands/nocturnal-rollout.d.ts +27 -0
- package/dist/commands/nocturnal-rollout.js +671 -0
- package/dist/commands/nocturnal-train.d.ts +25 -0
- package/dist/commands/nocturnal-train.js +919 -0
- package/dist/commands/pain.js +8 -21
- package/dist/constants/tools.d.ts +2 -2
- package/dist/constants/tools.js +1 -1
- package/dist/core/adaptive-thresholds.d.ts +186 -0
- package/dist/core/adaptive-thresholds.js +300 -0
- package/dist/core/config.d.ts +2 -38
- package/dist/core/config.js +6 -61
- package/dist/core/event-log.d.ts +1 -2
- package/dist/core/event-log.js +0 -3
- package/dist/core/evolution-engine.js +1 -21
- package/dist/core/evolution-reducer.d.ts +7 -1
- package/dist/core/evolution-reducer.js +56 -4
- package/dist/core/evolution-types.d.ts +61 -9
- package/dist/core/evolution-types.js +31 -9
- package/dist/core/external-training-contract.d.ts +276 -0
- package/dist/core/external-training-contract.js +269 -0
- package/dist/core/local-worker-routing.d.ts +175 -0
- package/dist/core/local-worker-routing.js +525 -0
- package/dist/core/model-deployment-registry.d.ts +218 -0
- package/dist/core/model-deployment-registry.js +503 -0
- package/dist/core/model-training-registry.d.ts +295 -0
- package/dist/core/model-training-registry.js +475 -0
- package/dist/core/nocturnal-arbiter.d.ts +159 -0
- package/dist/core/nocturnal-arbiter.js +534 -0
- package/dist/core/nocturnal-candidate-scoring.d.ts +137 -0
- package/dist/core/nocturnal-candidate-scoring.js +266 -0
- package/dist/core/nocturnal-compliance.d.ts +175 -0
- package/dist/core/nocturnal-compliance.js +824 -0
- package/dist/core/nocturnal-dataset.d.ts +224 -0
- package/dist/core/nocturnal-dataset.js +443 -0
- package/dist/core/nocturnal-executability.d.ts +85 -0
- package/dist/core/nocturnal-executability.js +331 -0
- package/dist/core/nocturnal-export.d.ts +124 -0
- package/dist/core/nocturnal-export.js +275 -0
- package/dist/core/nocturnal-paths.d.ts +124 -0
- package/dist/core/nocturnal-paths.js +214 -0
- package/dist/core/nocturnal-trajectory-extractor.d.ts +242 -0
- package/dist/core/nocturnal-trajectory-extractor.js +307 -0
- package/dist/core/nocturnal-trinity.d.ts +311 -0
- package/dist/core/nocturnal-trinity.js +880 -0
- package/dist/core/paths.d.ts +6 -0
- package/dist/core/paths.js +6 -0
- package/dist/core/principle-training-state.d.ts +121 -0
- package/dist/core/principle-training-state.js +321 -0
- package/dist/core/promotion-gate.d.ts +238 -0
- package/dist/core/promotion-gate.js +529 -0
- package/dist/core/session-tracker.d.ts +10 -0
- package/dist/core/session-tracker.js +14 -0
- package/dist/core/shadow-observation-registry.d.ts +217 -0
- package/dist/core/shadow-observation-registry.js +308 -0
- package/dist/core/training-program.d.ts +233 -0
- package/dist/core/training-program.js +433 -0
- package/dist/core/trajectory.d.ts +95 -1
- package/dist/core/trajectory.js +220 -6
- package/dist/core/workspace-context.d.ts +0 -6
- package/dist/core/workspace-context.js +0 -12
- package/dist/hooks/bash-risk.d.ts +6 -6
- package/dist/hooks/bash-risk.js +8 -8
- package/dist/hooks/gate-block-helper.js +1 -1
- package/dist/hooks/gate.d.ts +1 -1
- package/dist/hooks/gate.js +2 -2
- package/dist/hooks/gfi-gate.d.ts +3 -3
- package/dist/hooks/gfi-gate.js +15 -14
- package/dist/hooks/pain.js +6 -9
- package/dist/hooks/progressive-trust-gate.d.ts +21 -49
- package/dist/hooks/progressive-trust-gate.js +51 -204
- package/dist/hooks/prompt.d.ts +11 -11
- package/dist/hooks/prompt.js +158 -72
- package/dist/hooks/subagent.js +43 -6
- package/dist/i18n/commands.js +8 -8
- package/dist/index.js +129 -28
- package/dist/service/evolution-worker.d.ts +42 -4
- package/dist/service/evolution-worker.js +321 -13
- package/dist/service/nocturnal-runtime.d.ts +183 -0
- package/dist/service/nocturnal-runtime.js +352 -0
- package/dist/service/nocturnal-service.d.ts +163 -0
- package/dist/service/nocturnal-service.js +787 -0
- package/dist/service/nocturnal-target-selector.d.ts +145 -0
- package/dist/service/nocturnal-target-selector.js +315 -0
- package/dist/service/phase3-input-filter.d.ts +2 -23
- package/dist/service/phase3-input-filter.js +3 -27
- package/dist/service/runtime-summary-service.d.ts +0 -10
- package/dist/service/runtime-summary-service.js +1 -54
- package/dist/tools/deep-reflect.js +2 -1
- package/dist/types/event-types.d.ts +2 -10
- package/dist/types/runtime-summary.d.ts +1 -8
- package/dist/types.d.ts +0 -3
- package/dist/types.js +0 -2
- package/openclaw.plugin.json +1 -1
- package/package.json +1 -1
- package/templates/langs/en/skills/pd-mentor/SKILL.md +5 -5
- package/templates/langs/zh/skills/pd-mentor/SKILL.md +5 -5
- package/templates/pain_settings.json +0 -6
- package/dist/commands/trust.d.ts +0 -4
- package/dist/commands/trust.js +0 -78
- package/dist/core/trust-engine.d.ts +0 -96
- package/dist/core/trust-engine.js +0 -286
|
@@ -1,286 +0,0 @@
|
|
|
1
|
-
/**
|
|
2
|
-
* Trust Engine V2.1 - Recalibrated for Action Classification
|
|
3
|
-
* Differentiates between Exploratory (safe) and Constructive (risky) actions.
|
|
4
|
-
*/
|
|
5
|
-
import * as fs from 'fs';
|
|
6
|
-
import * as path from 'path';
|
|
7
|
-
import { EventLogService } from './event-log.js';
|
|
8
|
-
import { resolvePdPath } from './paths.js';
|
|
9
|
-
import { ConfigService } from './config-service.js';
|
|
10
|
-
import { TrajectoryRegistry } from './trajectory.js';
|
|
11
|
-
import { EXPLORATORY_TOOLS as SHARED_EXPLORATORY_TOOLS } from '../constants/tools.js';
|
|
12
|
-
export const EXPLORATORY_TOOLS = new Set(SHARED_EXPLORATORY_TOOLS);
|
|
13
|
-
const LEGACY_TRUST_REWARD_POLICY = 'frozen_all_positive';
|
|
14
|
-
export class TrustEngine {
|
|
15
|
-
scorecard;
|
|
16
|
-
workspaceDir;
|
|
17
|
-
stateDir;
|
|
18
|
-
constructor(workspaceDir) {
|
|
19
|
-
this.workspaceDir = workspaceDir;
|
|
20
|
-
this.stateDir = resolvePdPath(workspaceDir, 'STATE_DIR');
|
|
21
|
-
this.scorecard = this.loadScorecard();
|
|
22
|
-
const scorecardPath = resolvePdPath(this.workspaceDir, 'AGENT_SCORECARD');
|
|
23
|
-
if (!fs.existsSync(scorecardPath)) {
|
|
24
|
-
this.saveScorecard();
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
get config() {
|
|
28
|
-
return ConfigService.get(this.stateDir);
|
|
29
|
-
}
|
|
30
|
-
get trustSettings() {
|
|
31
|
-
const settings = this.config.get('trust');
|
|
32
|
-
return settings || {
|
|
33
|
-
stages: { stage_1_observer: 30, stage_2_editor: 60, stage_3_developer: 80 },
|
|
34
|
-
cold_start: { initial_trust: 85, grace_failures: 5, cold_start_period_ms: 86400000 },
|
|
35
|
-
// BUGFIX #84: Reduced penalties to prevent Trust collapse
|
|
36
|
-
penalties: { tool_failure_base: -1, risky_failure_base: -5, gate_bypass_attempt: -3, failure_streak_multiplier: -1, max_penalty: -10 },
|
|
37
|
-
rewards: { success_base: 2, subagent_success: 5, tool_success_reward: 0.2, streak_bonus_threshold: 3, streak_bonus: 5, recovery_boost: 5, max_reward: 15 },
|
|
38
|
-
limits: { stage_2_max_lines: 50, stage_3_max_lines: 300 }
|
|
39
|
-
};
|
|
40
|
-
}
|
|
41
|
-
loadScorecard() {
|
|
42
|
-
const scorecardPath = resolvePdPath(this.workspaceDir, 'AGENT_SCORECARD');
|
|
43
|
-
const settings = this.trustSettings;
|
|
44
|
-
if (fs.existsSync(scorecardPath)) {
|
|
45
|
-
try {
|
|
46
|
-
const raw = fs.readFileSync(scorecardPath, 'utf8');
|
|
47
|
-
const data = JSON.parse(raw);
|
|
48
|
-
if (data.score !== undefined && data.trust_score === undefined)
|
|
49
|
-
data.trust_score = data.score;
|
|
50
|
-
if (!data.history)
|
|
51
|
-
data.history = [];
|
|
52
|
-
if (data.exploratory_failure_streak === undefined)
|
|
53
|
-
data.exploratory_failure_streak = 0;
|
|
54
|
-
this.applyLegacyFreezeMetadata(data);
|
|
55
|
-
return data;
|
|
56
|
-
}
|
|
57
|
-
catch (e) {
|
|
58
|
-
console.error(`[PD:TrustEngine] FATAL: Failed to parse scorecard at ${scorecardPath}. Resetting.`);
|
|
59
|
-
}
|
|
60
|
-
}
|
|
61
|
-
const now = new Date();
|
|
62
|
-
const coldStartEnd = new Date(now.getTime() + settings.cold_start.cold_start_period_ms);
|
|
63
|
-
const scorecard = {
|
|
64
|
-
trust_score: settings.cold_start.initial_trust,
|
|
65
|
-
success_streak: 0,
|
|
66
|
-
failure_streak: 0,
|
|
67
|
-
exploratory_failure_streak: 0,
|
|
68
|
-
grace_failures_remaining: settings.cold_start.grace_failures,
|
|
69
|
-
last_updated: now.toISOString(),
|
|
70
|
-
cold_start_end: coldStartEnd.toISOString(),
|
|
71
|
-
first_activity_at: now.toISOString(),
|
|
72
|
-
history: []
|
|
73
|
-
};
|
|
74
|
-
this.applyLegacyFreezeMetadata(scorecard);
|
|
75
|
-
return scorecard;
|
|
76
|
-
}
|
|
77
|
-
applyLegacyFreezeMetadata(scorecard) {
|
|
78
|
-
scorecard.frozen = true;
|
|
79
|
-
scorecard.reward_policy = LEGACY_TRUST_REWARD_POLICY;
|
|
80
|
-
}
|
|
81
|
-
saveScorecard() {
|
|
82
|
-
const scorecardPath = resolvePdPath(this.workspaceDir, 'AGENT_SCORECARD');
|
|
83
|
-
try {
|
|
84
|
-
const dir = path.dirname(scorecardPath);
|
|
85
|
-
if (!fs.existsSync(dir))
|
|
86
|
-
fs.mkdirSync(dir, { recursive: true });
|
|
87
|
-
fs.writeFileSync(scorecardPath, JSON.stringify(this.scorecard, null, 2), 'utf8');
|
|
88
|
-
}
|
|
89
|
-
catch (e) {
|
|
90
|
-
console.error(`[PD:TrustEngine] Failed to save scorecard: ${String(e)}`);
|
|
91
|
-
}
|
|
92
|
-
}
|
|
93
|
-
getScore() { return this.scorecard.trust_score; }
|
|
94
|
-
getScorecard() { return this.scorecard; }
|
|
95
|
-
getStage() {
|
|
96
|
-
const score = this.scorecard.trust_score;
|
|
97
|
-
const stages = this.trustSettings.stages;
|
|
98
|
-
if (score < stages.stage_1_observer)
|
|
99
|
-
return 1;
|
|
100
|
-
if (score < stages.stage_2_editor)
|
|
101
|
-
return 2;
|
|
102
|
-
if (score < stages.stage_3_developer)
|
|
103
|
-
return 3;
|
|
104
|
-
return 4;
|
|
105
|
-
}
|
|
106
|
-
isColdStart() {
|
|
107
|
-
if (!this.scorecard.cold_start_end)
|
|
108
|
-
return false;
|
|
109
|
-
return new Date() < new Date(this.scorecard.cold_start_end);
|
|
110
|
-
}
|
|
111
|
-
recordSuccess(reason, context, isSubagent = false) {
|
|
112
|
-
const toolName = context?.toolName;
|
|
113
|
-
// 1. Check if this is an exploratory tool success
|
|
114
|
-
const isExploratory = toolName ? EXPLORATORY_TOOLS.has(toolName) : false;
|
|
115
|
-
if (reason === 'tool_success' && isExploratory) {
|
|
116
|
-
this.scorecard.exploratory_failure_streak = 0;
|
|
117
|
-
this.touchScorecard();
|
|
118
|
-
return;
|
|
119
|
-
}
|
|
120
|
-
// Phase 1 freeze: do not let atomic successes inflate legacy trust.
|
|
121
|
-
this.scorecard.success_streak = 0;
|
|
122
|
-
this.scorecard.failure_streak = 0; // Reset failure streak on constructive success
|
|
123
|
-
this.scorecard.exploratory_failure_streak = 0;
|
|
124
|
-
this.touchScorecard();
|
|
125
|
-
}
|
|
126
|
-
recordFailure(type, context) {
|
|
127
|
-
const settings = this.trustSettings;
|
|
128
|
-
const penalties = settings.penalties;
|
|
129
|
-
const toolName = context?.toolName;
|
|
130
|
-
// 1. Classification: Is this an exploratory failure?
|
|
131
|
-
const isExploratory = toolName ? EXPLORATORY_TOOLS.has(toolName) : false;
|
|
132
|
-
// 2. Cold start grace (only for non-risky actions)
|
|
133
|
-
if (type !== 'risky' && this.isColdStart() && (this.scorecard.grace_failures_remaining || 0) > 0) {
|
|
134
|
-
this.scorecard.grace_failures_remaining = (this.scorecard.grace_failures_remaining || 0) - 1;
|
|
135
|
-
this.updateScore(0, `Grace Failure consumed (${toolName || type})`, 'failure', context);
|
|
136
|
-
return;
|
|
137
|
-
}
|
|
138
|
-
if (isExploratory) {
|
|
139
|
-
// Exploratory failures are minor and don't trigger streak multipliers
|
|
140
|
-
this.scorecard.exploratory_failure_streak++;
|
|
141
|
-
this.updateScore(-1, `Exploratory Failure: ${toolName}`, 'failure', context);
|
|
142
|
-
return;
|
|
143
|
-
}
|
|
144
|
-
// BUGFIX #84: sessions_send timeout should not be penalized
|
|
145
|
-
// Communication timeouts are not agent failures - the message may have been delivered
|
|
146
|
-
const errorStr = String(context?.error || '');
|
|
147
|
-
if (toolName === 'sessions_send' && (errorStr.includes('timeout') || errorStr === 'timeout')) {
|
|
148
|
-
this.updateScore(0, `Communication timeout (sessions_send): ignored`, 'info', context);
|
|
149
|
-
return;
|
|
150
|
-
}
|
|
151
|
-
// 3. Constructive Failure (Risky or failed writes)
|
|
152
|
-
let delta = 0;
|
|
153
|
-
switch (type) {
|
|
154
|
-
case 'tool':
|
|
155
|
-
delta = penalties.tool_failure_base;
|
|
156
|
-
break;
|
|
157
|
-
case 'risky':
|
|
158
|
-
delta = penalties.risky_failure_base;
|
|
159
|
-
break;
|
|
160
|
-
case 'bypass':
|
|
161
|
-
delta = penalties.gate_bypass_attempt;
|
|
162
|
-
break;
|
|
163
|
-
}
|
|
164
|
-
this.scorecard.failure_streak++;
|
|
165
|
-
this.scorecard.success_streak = 0;
|
|
166
|
-
// Safety cap: streak multiplier only applies up to 5 consecutive failures
|
|
167
|
-
// to prevent "death spiral" from cascading errors
|
|
168
|
-
const effectiveStreak = Math.min(this.scorecard.failure_streak, 5);
|
|
169
|
-
if (effectiveStreak > 1) {
|
|
170
|
-
delta += (effectiveStreak - 1) * penalties.failure_streak_multiplier;
|
|
171
|
-
}
|
|
172
|
-
if (delta < penalties.max_penalty)
|
|
173
|
-
delta = penalties.max_penalty;
|
|
174
|
-
this.updateScore(delta, `Failure: ${toolName || type}`, 'failure', context);
|
|
175
|
-
}
|
|
176
|
-
touchScorecard() {
|
|
177
|
-
this.applyLegacyFreezeMetadata(this.scorecard);
|
|
178
|
-
this.scorecard.last_updated = new Date().toISOString();
|
|
179
|
-
this.saveScorecard();
|
|
180
|
-
}
|
|
181
|
-
updateScore(delta, reason, type, context) {
|
|
182
|
-
const oldScore = this.scorecard.trust_score;
|
|
183
|
-
this.applyLegacyFreezeMetadata(this.scorecard);
|
|
184
|
-
this.scorecard.trust_score += delta;
|
|
185
|
-
// Floor score: never drop below 30 (prevents Trust collapse from cascades)
|
|
186
|
-
if (this.scorecard.trust_score < 30)
|
|
187
|
-
this.scorecard.trust_score = 30;
|
|
188
|
-
if (this.scorecard.trust_score > 100)
|
|
189
|
-
this.scorecard.trust_score = 100;
|
|
190
|
-
this.scorecard.last_updated = new Date().toISOString();
|
|
191
|
-
if (!this.scorecard.history)
|
|
192
|
-
this.scorecard.history = [];
|
|
193
|
-
this.scorecard.history.push({ type, delta, reason, timestamp: new Date().toISOString() });
|
|
194
|
-
if (context?.sessionId) {
|
|
195
|
-
const eventLog = EventLogService.get(this.stateDir);
|
|
196
|
-
eventLog.recordTrustChange(context.sessionId, { previousScore: oldScore, newScore: this.scorecard.trust_score, delta, reason });
|
|
197
|
-
}
|
|
198
|
-
if (context?.sessionId) {
|
|
199
|
-
try {
|
|
200
|
-
TrajectoryRegistry.use(this.workspaceDir, (trajectory) => {
|
|
201
|
-
trajectory.recordTrustChange({
|
|
202
|
-
sessionId: context.sessionId,
|
|
203
|
-
previousScore: oldScore,
|
|
204
|
-
newScore: this.scorecard.trust_score,
|
|
205
|
-
delta,
|
|
206
|
-
reason,
|
|
207
|
-
});
|
|
208
|
-
});
|
|
209
|
-
}
|
|
210
|
-
catch {
|
|
211
|
-
// Do not block trust updates if trajectory storage is unavailable.
|
|
212
|
-
}
|
|
213
|
-
}
|
|
214
|
-
const limit = this.trustSettings.history_limit || 50;
|
|
215
|
-
if (this.scorecard.history.length > limit) {
|
|
216
|
-
this.scorecard.history.shift();
|
|
217
|
-
}
|
|
218
|
-
this.saveScorecard();
|
|
219
|
-
}
|
|
220
|
-
resetTrust(newScore) {
|
|
221
|
-
const settings = this.trustSettings;
|
|
222
|
-
const now = new Date();
|
|
223
|
-
const coldStartEnd = new Date(now.getTime() + settings.cold_start.cold_start_period_ms);
|
|
224
|
-
this.scorecard.trust_score = newScore ?? settings.cold_start.initial_trust;
|
|
225
|
-
this.scorecard.success_streak = 0;
|
|
226
|
-
this.scorecard.failure_streak = 0;
|
|
227
|
-
this.scorecard.exploratory_failure_streak = 0;
|
|
228
|
-
this.scorecard.grace_failures_remaining = settings.cold_start.grace_failures;
|
|
229
|
-
this.scorecard.last_updated = now.toISOString();
|
|
230
|
-
this.scorecard.first_activity_at = now.toISOString();
|
|
231
|
-
this.scorecard.cold_start_end = coldStartEnd.toISOString();
|
|
232
|
-
this.scorecard.history.push({ type: 'success', delta: 0, reason: 'Manual trust reset (Spiritual Cleanse)', timestamp: now.toISOString() });
|
|
233
|
-
this.applyLegacyFreezeMetadata(this.scorecard);
|
|
234
|
-
this.saveScorecard();
|
|
235
|
-
}
|
|
236
|
-
getStatusSummary() {
|
|
237
|
-
const scorecard = this.scorecard;
|
|
238
|
-
const successRate = this.calculateSuccessRate(scorecard);
|
|
239
|
-
return {
|
|
240
|
-
stage: this.getStage(),
|
|
241
|
-
successRate,
|
|
242
|
-
isInColdStart: this.isColdStart(),
|
|
243
|
-
graceRemaining: scorecard.grace_failures_remaining ?? 0,
|
|
244
|
-
currentStreak: {
|
|
245
|
-
type: scorecard.success_streak > scorecard.failure_streak ? 'success' : 'failure',
|
|
246
|
-
count: Math.max(scorecard.success_streak, scorecard.failure_streak)
|
|
247
|
-
}
|
|
248
|
-
};
|
|
249
|
-
}
|
|
250
|
-
calculateSuccessRate(scorecard) {
|
|
251
|
-
if (!scorecard.history || scorecard.history.length === 0)
|
|
252
|
-
return 100;
|
|
253
|
-
const recent = scorecard.history.slice(-20);
|
|
254
|
-
const successes = recent.filter(h => h.type === 'success').length;
|
|
255
|
-
return Math.round((successes / recent.length) * 100);
|
|
256
|
-
}
|
|
257
|
-
}
|
|
258
|
-
export function recordSuccess(workspaceDir, reason, context, isSubagent = false) {
|
|
259
|
-
new TrustEngine(workspaceDir).recordSuccess(reason, context, isSubagent);
|
|
260
|
-
}
|
|
261
|
-
export function recordFailure(type, workspaceDir, ctx) {
|
|
262
|
-
new TrustEngine(workspaceDir).recordFailure(type, ctx);
|
|
263
|
-
}
|
|
264
|
-
export function getAgentScorecard(workspaceDir) {
|
|
265
|
-
return new TrustEngine(workspaceDir).getScorecard();
|
|
266
|
-
}
|
|
267
|
-
export function getTrustStats(scorecard) {
|
|
268
|
-
const dummy = new TrustEngine(process.cwd());
|
|
269
|
-
const successRate = dummy.calculateSuccessRate(scorecard);
|
|
270
|
-
const stages = { stage_1_observer: 30, stage_2_editor: 60, stage_3_developer: 80 };
|
|
271
|
-
let stage = scorecard.trust_score < stages.stage_1_observer ? 1 :
|
|
272
|
-
scorecard.trust_score < stages.stage_2_editor ? 2 :
|
|
273
|
-
scorecard.trust_score < stages.stage_3_developer ? 3 : 4;
|
|
274
|
-
return {
|
|
275
|
-
stage, successRate,
|
|
276
|
-
isInColdStart: scorecard.cold_start_end ? new Date() < new Date(scorecard.cold_start_end) : false,
|
|
277
|
-
graceRemaining: scorecard.grace_failures_remaining ?? 0,
|
|
278
|
-
currentStreak: {
|
|
279
|
-
type: (scorecard.success_streak || 0) > (scorecard.failure_streak || 0) ? 'success' : 'failure',
|
|
280
|
-
count: Math.max(scorecard.success_streak || 0, scorecard.failure_streak || 0)
|
|
281
|
-
}
|
|
282
|
-
};
|
|
283
|
-
}
|
|
284
|
-
export function getTrustStatus(workspaceDir) {
|
|
285
|
-
return new TrustEngine(workspaceDir).getStatusSummary();
|
|
286
|
-
}
|