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.
Files changed (106) hide show
  1. package/dist/commands/context.js +5 -15
  2. package/dist/commands/evolution-status.js +2 -9
  3. package/dist/commands/export.js +61 -8
  4. package/dist/commands/nocturnal-review.d.ts +24 -0
  5. package/dist/commands/nocturnal-review.js +265 -0
  6. package/dist/commands/nocturnal-rollout.d.ts +27 -0
  7. package/dist/commands/nocturnal-rollout.js +671 -0
  8. package/dist/commands/nocturnal-train.d.ts +25 -0
  9. package/dist/commands/nocturnal-train.js +919 -0
  10. package/dist/commands/pain.js +8 -21
  11. package/dist/constants/tools.d.ts +2 -2
  12. package/dist/constants/tools.js +1 -1
  13. package/dist/core/adaptive-thresholds.d.ts +186 -0
  14. package/dist/core/adaptive-thresholds.js +300 -0
  15. package/dist/core/config.d.ts +2 -38
  16. package/dist/core/config.js +6 -61
  17. package/dist/core/event-log.d.ts +1 -2
  18. package/dist/core/event-log.js +0 -3
  19. package/dist/core/evolution-engine.js +1 -21
  20. package/dist/core/evolution-reducer.d.ts +7 -1
  21. package/dist/core/evolution-reducer.js +56 -4
  22. package/dist/core/evolution-types.d.ts +61 -9
  23. package/dist/core/evolution-types.js +31 -9
  24. package/dist/core/external-training-contract.d.ts +276 -0
  25. package/dist/core/external-training-contract.js +269 -0
  26. package/dist/core/local-worker-routing.d.ts +175 -0
  27. package/dist/core/local-worker-routing.js +525 -0
  28. package/dist/core/model-deployment-registry.d.ts +218 -0
  29. package/dist/core/model-deployment-registry.js +503 -0
  30. package/dist/core/model-training-registry.d.ts +295 -0
  31. package/dist/core/model-training-registry.js +475 -0
  32. package/dist/core/nocturnal-arbiter.d.ts +159 -0
  33. package/dist/core/nocturnal-arbiter.js +534 -0
  34. package/dist/core/nocturnal-candidate-scoring.d.ts +137 -0
  35. package/dist/core/nocturnal-candidate-scoring.js +266 -0
  36. package/dist/core/nocturnal-compliance.d.ts +175 -0
  37. package/dist/core/nocturnal-compliance.js +824 -0
  38. package/dist/core/nocturnal-dataset.d.ts +224 -0
  39. package/dist/core/nocturnal-dataset.js +443 -0
  40. package/dist/core/nocturnal-executability.d.ts +85 -0
  41. package/dist/core/nocturnal-executability.js +331 -0
  42. package/dist/core/nocturnal-export.d.ts +124 -0
  43. package/dist/core/nocturnal-export.js +275 -0
  44. package/dist/core/nocturnal-paths.d.ts +124 -0
  45. package/dist/core/nocturnal-paths.js +214 -0
  46. package/dist/core/nocturnal-trajectory-extractor.d.ts +242 -0
  47. package/dist/core/nocturnal-trajectory-extractor.js +307 -0
  48. package/dist/core/nocturnal-trinity.d.ts +311 -0
  49. package/dist/core/nocturnal-trinity.js +880 -0
  50. package/dist/core/paths.d.ts +6 -0
  51. package/dist/core/paths.js +6 -0
  52. package/dist/core/principle-training-state.d.ts +121 -0
  53. package/dist/core/principle-training-state.js +321 -0
  54. package/dist/core/promotion-gate.d.ts +238 -0
  55. package/dist/core/promotion-gate.js +529 -0
  56. package/dist/core/session-tracker.d.ts +10 -0
  57. package/dist/core/session-tracker.js +14 -0
  58. package/dist/core/shadow-observation-registry.d.ts +217 -0
  59. package/dist/core/shadow-observation-registry.js +308 -0
  60. package/dist/core/training-program.d.ts +233 -0
  61. package/dist/core/training-program.js +433 -0
  62. package/dist/core/trajectory.d.ts +95 -1
  63. package/dist/core/trajectory.js +220 -6
  64. package/dist/core/workspace-context.d.ts +0 -6
  65. package/dist/core/workspace-context.js +0 -12
  66. package/dist/hooks/bash-risk.d.ts +6 -6
  67. package/dist/hooks/bash-risk.js +8 -8
  68. package/dist/hooks/gate-block-helper.js +1 -1
  69. package/dist/hooks/gate.d.ts +1 -1
  70. package/dist/hooks/gate.js +2 -2
  71. package/dist/hooks/gfi-gate.d.ts +3 -3
  72. package/dist/hooks/gfi-gate.js +15 -14
  73. package/dist/hooks/pain.js +6 -9
  74. package/dist/hooks/progressive-trust-gate.d.ts +21 -49
  75. package/dist/hooks/progressive-trust-gate.js +51 -204
  76. package/dist/hooks/prompt.d.ts +11 -11
  77. package/dist/hooks/prompt.js +158 -72
  78. package/dist/hooks/subagent.js +43 -6
  79. package/dist/i18n/commands.js +8 -8
  80. package/dist/index.js +129 -28
  81. package/dist/service/evolution-worker.d.ts +42 -4
  82. package/dist/service/evolution-worker.js +321 -13
  83. package/dist/service/nocturnal-runtime.d.ts +183 -0
  84. package/dist/service/nocturnal-runtime.js +352 -0
  85. package/dist/service/nocturnal-service.d.ts +163 -0
  86. package/dist/service/nocturnal-service.js +787 -0
  87. package/dist/service/nocturnal-target-selector.d.ts +145 -0
  88. package/dist/service/nocturnal-target-selector.js +315 -0
  89. package/dist/service/phase3-input-filter.d.ts +2 -23
  90. package/dist/service/phase3-input-filter.js +3 -27
  91. package/dist/service/runtime-summary-service.d.ts +0 -10
  92. package/dist/service/runtime-summary-service.js +1 -54
  93. package/dist/tools/deep-reflect.js +2 -1
  94. package/dist/types/event-types.d.ts +2 -10
  95. package/dist/types/runtime-summary.d.ts +1 -8
  96. package/dist/types.d.ts +0 -3
  97. package/dist/types.js +0 -2
  98. package/openclaw.plugin.json +1 -1
  99. package/package.json +1 -1
  100. package/templates/langs/en/skills/pd-mentor/SKILL.md +5 -5
  101. package/templates/langs/zh/skills/pd-mentor/SKILL.md +5 -5
  102. package/templates/pain_settings.json +0 -6
  103. package/dist/commands/trust.d.ts +0 -4
  104. package/dist/commands/trust.js +0 -78
  105. package/dist/core/trust-engine.d.ts +0 -96
  106. package/dist/core/trust-engine.js +0 -286
@@ -89,7 +89,9 @@ export interface TrajectorySessionInput {
89
89
  sessionId: string;
90
90
  startedAt?: string;
91
91
  }
92
- export interface EvolutionTaskInput {
92
+ export type TaskKind = 'pain_diagnosis' | 'sleep_reflection' | 'model_eval';
93
+ export type TaskPriority = 'high' | 'medium' | 'low';
94
+ interface EvolutionTaskInputBase {
93
95
  taskId: string;
94
96
  traceId: string;
95
97
  source: string;
@@ -103,6 +105,16 @@ export interface EvolutionTaskInput {
103
105
  createdAt?: string;
104
106
  updatedAt?: string;
105
107
  }
108
+ interface EvolutionTaskInputV2 extends EvolutionTaskInputBase {
109
+ taskKind?: TaskKind;
110
+ priority?: TaskPriority;
111
+ retryCount?: number;
112
+ maxRetries?: number;
113
+ lastError?: string | null;
114
+ resultRef?: string | null;
115
+ }
116
+ export type EvolutionTaskInput = EvolutionTaskInputV2;
117
+ export { EvolutionTaskInputV2 };
106
118
  export interface EvolutionEventInput {
107
119
  traceId: string;
108
120
  taskId?: string | null;
@@ -127,6 +139,12 @@ export interface EvolutionTaskRecord {
127
139
  resolution: string | null;
128
140
  createdAt: string;
129
141
  updatedAt: string;
142
+ taskKind: TaskKind | null;
143
+ priority: TaskPriority | null;
144
+ retryCount: number | null;
145
+ maxRetries: number | null;
146
+ lastError: string | null;
147
+ resultRef: string | null;
130
148
  }
131
149
  export interface EvolutionEventRecord {
132
150
  id: number;
@@ -242,6 +260,24 @@ export declare class TrajectoryDatabase {
242
260
  completed: number;
243
261
  failed: number;
244
262
  };
263
+ /**
264
+ * List recent sessions from the trajectory database.
265
+ *
266
+ * Returns: Recent session records ordered by most recently updated.
267
+ *
268
+ * @param options.limit - Maximum number of sessions to return (default: 20)
269
+ * @param options.dateFrom - Only return sessions updated after this date
270
+ * @param options.dateTo - Only return sessions updated before this date
271
+ */
272
+ listRecentSessions(options?: {
273
+ limit?: number;
274
+ dateFrom?: string;
275
+ dateTo?: string;
276
+ }): Array<{
277
+ sessionId: string;
278
+ startedAt: string;
279
+ updatedAt: string;
280
+ }>;
245
281
  /**
246
282
  * List assistant turns for a session.
247
283
  *
@@ -249,6 +285,52 @@ export declare class TrajectoryDatabase {
249
285
  * Not: Runtime truth or real-time queue state.
250
286
  */
251
287
  listAssistantTurns(sessionId: string): AssistantTurnRecord[];
288
+ /**
289
+ * List tool calls for a session.
290
+ *
291
+ * Returns: Analytics data aggregated from trajectory database.
292
+ * Not: Runtime truth or real-time queue state.
293
+ */
294
+ listToolCallsForSession(sessionId: string): Array<{
295
+ id: number;
296
+ toolName: string;
297
+ outcome: string;
298
+ filePath: string | null;
299
+ durationMs: number | null;
300
+ exitCode: number | null;
301
+ errorType: string | null;
302
+ errorMessage: string | null;
303
+ gfiBefore: number | null;
304
+ gfiAfter: number | null;
305
+ createdAt: string;
306
+ }>;
307
+ /**
308
+ * List pain events for a session.
309
+ *
310
+ * Returns: Analytics data aggregated from trajectory database.
311
+ * Not: Runtime truth or real-time queue state.
312
+ */
313
+ listPainEventsForSession(sessionId: string): Array<{
314
+ id: number;
315
+ source: string;
316
+ score: number;
317
+ reason: string | null;
318
+ severity: string | null;
319
+ origin: string | null;
320
+ confidence: number | null;
321
+ createdAt: string;
322
+ }>;
323
+ /**
324
+ * List user turns for a session.
325
+ * Returns sanitized/reduced fields for nocturnal use — NO raw text.
326
+ */
327
+ listUserTurnsForSession(sessionId: string): Array<{
328
+ id: number;
329
+ turnIndex: number;
330
+ correctionDetected: boolean;
331
+ correctionCue: string | null;
332
+ createdAt: string;
333
+ }>;
252
334
  /**
253
335
  * List correction samples with optional review status filter.
254
336
  *
@@ -256,6 +338,18 @@ export declare class TrajectoryDatabase {
256
338
  * Not: Runtime truth or real-time queue state.
257
339
  */
258
340
  listCorrectionSamples(status?: CorrectionSampleReviewStatus): CorrectionSampleRecord[];
341
+ /**
342
+ * List gate blocks for a session.
343
+ * Returns minimal fields for nocturnal use — no raw text.
344
+ */
345
+ listGateBlocksForSession(sessionId: string): Array<{
346
+ id: number;
347
+ toolName: string;
348
+ filePath: string | null;
349
+ reason: string;
350
+ planStatus: string | null;
351
+ createdAt: string;
352
+ }>;
259
353
  reviewCorrectionSample(sampleId: string, status: Exclude<CorrectionSampleReviewStatus, 'pending'>, note?: string): CorrectionSampleRecord;
260
354
  /**
261
355
  * Export correction samples to JSONL file.
@@ -115,6 +115,9 @@ export class TrajectoryDatabase {
115
115
  recordToolCall(input) {
116
116
  this.recordSession({ sessionId: input.sessionId, startedAt: input.createdAt });
117
117
  const createdAt = input.createdAt ?? nowIso();
118
+ // Extract filePath from paramsJson if provided and is an object with filePath
119
+ const paramsObj = input.paramsJson;
120
+ const filePath = paramsObj && typeof paramsObj.filePath === 'string' ? paramsObj.filePath : null;
118
121
  const rowId = this.withWrite(() => {
119
122
  const result = this.db.prepare(`
120
123
  INSERT INTO tool_calls (
@@ -173,23 +176,34 @@ export class TrajectoryDatabase {
173
176
  }
174
177
  recordEvolutionTask(input) {
175
178
  const now = nowIso();
179
+ // Cast to V2 to access new fields
180
+ const v2 = input;
176
181
  this.withWrite(() => {
177
182
  this.db.prepare(`
178
183
  INSERT INTO evolution_tasks (
179
184
  task_id, trace_id, source, reason, score, status,
180
- enqueued_at, started_at, completed_at, resolution, created_at, updated_at
181
- ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
185
+ enqueued_at, started_at, completed_at, resolution, created_at, updated_at,
186
+ task_kind, priority, retry_count, max_retries, last_error, result_ref
187
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
182
188
  ON CONFLICT(task_id) DO UPDATE SET
183
189
  status = excluded.status,
184
190
  started_at = excluded.started_at,
185
191
  completed_at = excluded.completed_at,
186
192
  resolution = excluded.resolution,
187
- updated_at = excluded.updated_at
188
- `).run(input.taskId, input.traceId, input.source, input.reason ?? null, input.score ?? 0, input.status ?? 'pending', input.enqueuedAt ?? null, input.startedAt ?? null, input.completedAt ?? null, input.resolution ?? null, input.createdAt ?? now, input.updatedAt ?? now);
193
+ updated_at = excluded.updated_at,
194
+ task_kind = excluded.task_kind,
195
+ priority = excluded.priority,
196
+ retry_count = excluded.retry_count,
197
+ max_retries = excluded.max_retries,
198
+ last_error = excluded.last_error,
199
+ result_ref = excluded.result_ref
200
+ `).run(input.taskId, input.traceId, input.source, input.reason ?? null, input.score ?? 0, input.status ?? 'pending', input.enqueuedAt ?? null, input.startedAt ?? null, input.completedAt ?? null, input.resolution ?? null, input.createdAt ?? now, input.updatedAt ?? now, v2.taskKind ?? null, v2.priority ?? null, v2.retryCount ?? null, v2.maxRetries ?? null, v2.lastError ?? null, v2.resultRef ?? null);
189
201
  });
190
202
  }
191
203
  updateEvolutionTask(taskId, updates) {
192
204
  const now = nowIso();
205
+ // Cast to V2 to access new fields
206
+ const v2Updates = updates;
193
207
  this.withWrite(() => {
194
208
  const setClauses = ['updated_at = ?'];
195
209
  const values = [now];
@@ -213,6 +227,31 @@ export class TrajectoryDatabase {
213
227
  setClauses.push('score = ?');
214
228
  values.push(updates.score);
215
229
  }
230
+ // V2 fields
231
+ if (v2Updates.taskKind !== undefined) {
232
+ setClauses.push('task_kind = ?');
233
+ values.push(v2Updates.taskKind);
234
+ }
235
+ if (v2Updates.priority !== undefined) {
236
+ setClauses.push('priority = ?');
237
+ values.push(v2Updates.priority);
238
+ }
239
+ if (v2Updates.retryCount !== undefined) {
240
+ setClauses.push('retry_count = ?');
241
+ values.push(v2Updates.retryCount);
242
+ }
243
+ if (v2Updates.maxRetries !== undefined) {
244
+ setClauses.push('max_retries = ?');
245
+ values.push(v2Updates.maxRetries);
246
+ }
247
+ if (v2Updates.lastError !== undefined) {
248
+ setClauses.push('last_error = ?');
249
+ values.push(v2Updates.lastError);
250
+ }
251
+ if (v2Updates.resultRef !== undefined) {
252
+ setClauses.push('result_ref = ?');
253
+ values.push(v2Updates.resultRef);
254
+ }
216
255
  values.push(taskId);
217
256
  this.db.prepare(`
218
257
  UPDATE evolution_tasks SET ${setClauses.join(', ')} WHERE task_id = ?
@@ -253,7 +292,8 @@ export class TrajectoryDatabase {
253
292
  const offset = filters.offset ?? 0;
254
293
  const rows = this.db.prepare(`
255
294
  SELECT id, task_id, trace_id, source, reason, score, status,
256
- enqueued_at, started_at, completed_at, resolution, created_at, updated_at
295
+ enqueued_at, started_at, completed_at, resolution, created_at, updated_at,
296
+ task_kind, priority, retry_count, max_retries, last_error, result_ref
257
297
  FROM evolution_tasks
258
298
  ${whereClause}
259
299
  ORDER BY created_at DESC
@@ -273,6 +313,12 @@ export class TrajectoryDatabase {
273
313
  resolution: row.resolution ? String(row.resolution) : null,
274
314
  createdAt: String(row.created_at),
275
315
  updatedAt: String(row.updated_at),
316
+ taskKind: row.task_kind ? row.task_kind : null,
317
+ priority: row.priority ? row.priority : null,
318
+ retryCount: row.retry_count != null ? Number(row.retry_count) : null,
319
+ maxRetries: row.max_retries != null ? Number(row.max_retries) : null,
320
+ lastError: row.last_error ? String(row.last_error) : null,
321
+ resultRef: row.result_ref ? String(row.result_ref) : null,
276
322
  }));
277
323
  }
278
324
  /**
@@ -323,7 +369,8 @@ export class TrajectoryDatabase {
323
369
  getEvolutionTaskByTraceId(traceId) {
324
370
  const row = this.db.prepare(`
325
371
  SELECT id, task_id, trace_id, source, reason, score, status,
326
- enqueued_at, started_at, completed_at, resolution, created_at, updated_at
372
+ enqueued_at, started_at, completed_at, resolution, created_at, updated_at,
373
+ task_kind, priority, retry_count, max_retries, last_error, result_ref
327
374
  FROM evolution_tasks
328
375
  WHERE trace_id = ?
329
376
  LIMIT 1
@@ -344,6 +391,12 @@ export class TrajectoryDatabase {
344
391
  resolution: row.resolution ? String(row.resolution) : null,
345
392
  createdAt: String(row.created_at),
346
393
  updatedAt: String(row.updated_at),
394
+ taskKind: row.task_kind ? row.task_kind : null,
395
+ priority: row.priority ? row.priority : null,
396
+ retryCount: row.retry_count != null ? Number(row.retry_count) : null,
397
+ maxRetries: row.max_retries != null ? Number(row.max_retries) : null,
398
+ lastError: row.last_error ? String(row.last_error) : null,
399
+ resultRef: row.result_ref ? String(row.result_ref) : null,
347
400
  };
348
401
  }
349
402
  /**
@@ -370,6 +423,41 @@ export class TrajectoryDatabase {
370
423
  }
371
424
  return stats;
372
425
  }
426
+ /**
427
+ * List recent sessions from the trajectory database.
428
+ *
429
+ * Returns: Recent session records ordered by most recently updated.
430
+ *
431
+ * @param options.limit - Maximum number of sessions to return (default: 20)
432
+ * @param options.dateFrom - Only return sessions updated after this date
433
+ * @param options.dateTo - Only return sessions updated before this date
434
+ */
435
+ listRecentSessions(options = {}) {
436
+ const conditions = [];
437
+ const values = [];
438
+ if (options.dateFrom) {
439
+ conditions.push('updated_at >= ?');
440
+ values.push(options.dateFrom);
441
+ }
442
+ if (options.dateTo) {
443
+ conditions.push('updated_at <= ?');
444
+ values.push(options.dateTo);
445
+ }
446
+ const whereClause = conditions.length > 0 ? `WHERE ${conditions.join(' AND ')}` : '';
447
+ const limit = options.limit ?? 20;
448
+ const rows = this.db.prepare(`
449
+ SELECT session_id, started_at, updated_at
450
+ FROM sessions
451
+ ${whereClause}
452
+ ORDER BY updated_at DESC
453
+ LIMIT ?
454
+ `).all(...values, limit);
455
+ return rows.map((row) => ({
456
+ sessionId: String(row.session_id),
457
+ startedAt: String(row.started_at),
458
+ updatedAt: String(row.updated_at),
459
+ }));
460
+ }
373
461
  /**
374
462
  * List assistant turns for a session.
375
463
  *
@@ -395,6 +483,92 @@ export class TrajectoryDatabase {
395
483
  createdAt: String(row.created_at),
396
484
  }));
397
485
  }
486
+ /**
487
+ * List tool calls for a session.
488
+ *
489
+ * Returns: Analytics data aggregated from trajectory database.
490
+ * Not: Runtime truth or real-time queue state.
491
+ */
492
+ listToolCallsForSession(sessionId) {
493
+ const rows = this.db.prepare(`
494
+ SELECT id, tool_name, outcome, params_json, duration_ms, exit_code, error_type, error_message,
495
+ gfi_before, gfi_after, created_at
496
+ FROM tool_calls
497
+ WHERE session_id = ?
498
+ ORDER BY id ASC
499
+ `).all(sessionId);
500
+ return rows.map((row) => {
501
+ // Extract filePath from params_json if present
502
+ let filePath = null;
503
+ if (row.params_json && typeof row.params_json === 'string') {
504
+ try {
505
+ const params = JSON.parse(row.params_json);
506
+ if (params && typeof params.filePath === 'string') {
507
+ filePath = params.filePath;
508
+ }
509
+ }
510
+ catch {
511
+ // Ignore malformed JSON
512
+ }
513
+ }
514
+ return {
515
+ id: Number(row.id),
516
+ toolName: String(row.tool_name),
517
+ outcome: String(row.outcome),
518
+ filePath,
519
+ durationMs: row.duration_ms != null ? Number(row.duration_ms) : null,
520
+ exitCode: row.exit_code != null ? Number(row.exit_code) : null,
521
+ errorType: row.error_type ? String(row.error_type) : null,
522
+ errorMessage: row.error_message ? String(row.error_message) : null,
523
+ gfiBefore: row.gfi_before != null ? Number(row.gfi_before) : null,
524
+ gfiAfter: row.gfi_after != null ? Number(row.gfi_after) : null,
525
+ createdAt: String(row.created_at),
526
+ };
527
+ });
528
+ }
529
+ /**
530
+ * List pain events for a session.
531
+ *
532
+ * Returns: Analytics data aggregated from trajectory database.
533
+ * Not: Runtime truth or real-time queue state.
534
+ */
535
+ listPainEventsForSession(sessionId) {
536
+ const rows = this.db.prepare(`
537
+ SELECT id, source, score, reason, severity, origin, confidence, created_at
538
+ FROM pain_events
539
+ WHERE session_id = ?
540
+ ORDER BY created_at ASC
541
+ `).all(sessionId);
542
+ return rows.map((row) => ({
543
+ id: Number(row.id),
544
+ source: String(row.source),
545
+ score: Number(row.score),
546
+ reason: row.reason ? String(row.reason) : null,
547
+ severity: row.severity ? String(row.severity) : null,
548
+ origin: row.origin ? String(row.origin) : null,
549
+ confidence: row.confidence != null ? Number(row.confidence) : null,
550
+ createdAt: String(row.created_at),
551
+ }));
552
+ }
553
+ /**
554
+ * List user turns for a session.
555
+ * Returns sanitized/reduced fields for nocturnal use — NO raw text.
556
+ */
557
+ listUserTurnsForSession(sessionId) {
558
+ const rows = this.db.prepare(`
559
+ SELECT id, turn_index, correction_detected, correction_cue, created_at
560
+ FROM user_turns
561
+ WHERE session_id = ?
562
+ ORDER BY turn_index ASC
563
+ `).all(sessionId);
564
+ return rows.map((row) => ({
565
+ id: Number(row.id),
566
+ turnIndex: Number(row.turn_index),
567
+ correctionDetected: Boolean(row.correction_detected),
568
+ correctionCue: row.correction_cue ? String(row.correction_cue) : null,
569
+ createdAt: String(row.created_at),
570
+ }));
571
+ }
398
572
  /**
399
573
  * List correction samples with optional review status filter.
400
574
  *
@@ -425,6 +599,26 @@ export class TrajectoryDatabase {
425
599
  updatedAt: String(row.updated_at),
426
600
  }));
427
601
  }
602
+ /**
603
+ * List gate blocks for a session.
604
+ * Returns minimal fields for nocturnal use — no raw text.
605
+ */
606
+ listGateBlocksForSession(sessionId) {
607
+ const rows = this.db.prepare(`
608
+ SELECT id, tool_name, file_path, reason, plan_status, created_at
609
+ FROM gate_blocks
610
+ WHERE session_id = ?
611
+ ORDER BY id ASC
612
+ `).all(sessionId);
613
+ return rows.map((row) => ({
614
+ id: Number(row.id),
615
+ toolName: String(row.tool_name),
616
+ filePath: row.file_path ? String(row.file_path) : null,
617
+ reason: String(row.reason),
618
+ planStatus: row.plan_status ? String(row.plan_status) : null,
619
+ createdAt: String(row.created_at),
620
+ }));
621
+ }
428
622
  reviewCorrectionSample(sampleId, status, note) {
429
623
  const updatedAt = nowIso();
430
624
  const updated = this.withWrite(() => {
@@ -722,6 +916,26 @@ export class TrajectoryDatabase {
722
916
  metadata_json TEXT,
723
917
  created_at TEXT NOT NULL
724
918
  );
919
+ `);
920
+ // V2 migration: Add V2 columns to evolution_tasks if they don't exist
921
+ // SQLite does not support IF NOT EXISTS for ADD COLUMN, so we must check manually
922
+ // before each ALTER to avoid "duplicate column name" errors on existing DBs
923
+ const v2Columns = [
924
+ { name: 'task_kind', type: 'TEXT' },
925
+ { name: 'priority', type: 'TEXT' },
926
+ { name: 'retry_count', type: 'INTEGER' },
927
+ { name: 'max_retries', type: 'INTEGER' },
928
+ { name: 'last_error', type: 'TEXT' },
929
+ { name: 'result_ref', type: 'TEXT' },
930
+ ];
931
+ for (const col of v2Columns) {
932
+ const exists = this.db.prepare(`PRAGMA table_info(evolution_tasks)`).all()
933
+ .some((row) => row.name === col.name);
934
+ if (!exists) {
935
+ this.db.exec(`ALTER TABLE evolution_tasks ADD COLUMN ${col.name} ${col.type}`);
936
+ }
937
+ }
938
+ this.db.exec(`
725
939
  CREATE VIEW IF NOT EXISTS v_error_clusters AS
726
940
  SELECT tool_name, COALESCE(error_type, 'unknown') AS error_type, COUNT(*) AS occurrences
727
941
  FROM tool_calls
@@ -2,7 +2,6 @@ import { PD_FILES } from './paths.js';
2
2
  import { PainConfig } from './config.js';
3
3
  import { EventLog } from './event-log.js';
4
4
  import { PainDictionary } from './dictionary.js';
5
- import { TrustEngine } from './trust-engine.js';
6
5
  import { HygieneTracker } from './hygiene/tracker.js';
7
6
  import { EvolutionReducerImpl } from './evolution-reducer.js';
8
7
  import { TrajectoryDatabase } from './trajectory.js';
@@ -18,7 +17,6 @@ export declare class WorkspaceContext {
18
17
  private _config?;
19
18
  private _eventLog?;
20
19
  private _dictionary?;
21
- private _trust?;
22
20
  private _hygiene?;
23
21
  private _evolutionReducer?;
24
22
  private _trajectory?;
@@ -35,10 +33,6 @@ export declare class WorkspaceContext {
35
33
  * Pain dictionary service for this workspace.
36
34
  */
37
35
  get dictionary(): PainDictionary;
38
- /**
39
- * Trust engine service bound to this workspace.
40
- */
41
- get trust(): TrustEngine;
42
36
  /**
43
37
  * Hygiene tracking service for this workspace.
44
38
  */
@@ -3,7 +3,6 @@ import { PathResolver } from './path-resolver.js';
3
3
  import { ConfigService } from './config-service.js';
4
4
  import { EventLogService } from './event-log.js';
5
5
  import { DictionaryService } from './dictionary-service.js';
6
- import { TrustEngine } from './trust-engine.js';
7
6
  import { HygieneTracker } from './hygiene/tracker.js';
8
7
  import { EvolutionReducerImpl } from './evolution-reducer.js';
9
8
  import { TrajectoryRegistry } from './trajectory.js';
@@ -19,7 +18,6 @@ export class WorkspaceContext {
19
18
  _config;
20
19
  _eventLog;
21
20
  _dictionary;
22
- _trust;
23
21
  _hygiene;
24
22
  _evolutionReducer;
25
23
  _trajectory;
@@ -54,15 +52,6 @@ export class WorkspaceContext {
54
52
  }
55
53
  return this._dictionary;
56
54
  }
57
- /**
58
- * Trust engine service bound to this workspace.
59
- */
60
- get trust() {
61
- if (!this._trust) {
62
- this._trust = new TrustEngine(this.workspaceDir);
63
- }
64
- return this._trust;
65
- }
66
55
  /**
67
56
  * Hygiene tracking service for this workspace.
68
57
  */
@@ -148,7 +137,6 @@ export class WorkspaceContext {
148
137
  this._config = undefined;
149
138
  this._eventLog = undefined;
150
139
  this._dictionary = undefined;
151
- this._trust = undefined;
152
140
  this._evolutionReducer = undefined;
153
141
  this._trajectory = undefined;
154
142
  }
@@ -39,19 +39,19 @@ export declare function analyzeBashCommand(command: string, safePatterns: string
39
39
  }): BashRiskLevel;
40
40
  export interface DynamicThresholdConfig {
41
41
  large_change_lines: number;
42
- trust_stage_multipliers: Record<string, number>;
42
+ ep_tier_multipliers: Record<string, number>;
43
43
  }
44
44
  /**
45
- * Calculates the dynamic GFI threshold based on trust stage and line changes.
45
+ * Calculates the dynamic GFI threshold based on EP tier and line changes.
46
46
  *
47
47
  * The threshold is adjusted by:
48
- * 1. Trust stage multiplier (higher stages get higher thresholds)
48
+ * 1. EP tier multiplier (higher tiers get higher thresholds)
49
49
  * 2. Large change reduction (big edits lower the threshold to catch more issues)
50
50
  *
51
51
  * @param baseThreshold - The base GFI threshold (typically 50 for GFI)
52
- * @param trustStage - Current trust stage (1-4)
52
+ * @param epTier - Current EP tier (1-5)
53
53
  * @param lineChanges - Number of lines being changed
54
- * @param config - Configuration with large_change_lines and trust_stage_multipliers
54
+ * @param config - Configuration with large_change_lines and ep_tier_multipliers
55
55
  * @returns The adjusted threshold (minimum 0)
56
56
  */
57
- export declare function calculateDynamicThreshold(baseThreshold: number, trustStage: number, lineChanges: number, config: DynamicThresholdConfig): number;
57
+ export declare function calculateDynamicThreshold(baseThreshold: number, epTier: number, lineChanges: number, config: DynamicThresholdConfig): number;
@@ -112,22 +112,22 @@ export function analyzeBashCommand(command, safePatterns, dangerousPatterns, log
112
112
  return 'safe';
113
113
  }
114
114
  /**
115
- * Calculates the dynamic GFI threshold based on trust stage and line changes.
115
+ * Calculates the dynamic GFI threshold based on EP tier and line changes.
116
116
  *
117
117
  * The threshold is adjusted by:
118
- * 1. Trust stage multiplier (higher stages get higher thresholds)
118
+ * 1. EP tier multiplier (higher tiers get higher thresholds)
119
119
  * 2. Large change reduction (big edits lower the threshold to catch more issues)
120
120
  *
121
121
  * @param baseThreshold - The base GFI threshold (typically 50 for GFI)
122
- * @param trustStage - Current trust stage (1-4)
122
+ * @param epTier - Current EP tier (1-5)
123
123
  * @param lineChanges - Number of lines being changed
124
- * @param config - Configuration with large_change_lines and trust_stage_multipliers
124
+ * @param config - Configuration with large_change_lines and ep_tier_multipliers
125
125
  * @returns The adjusted threshold (minimum 0)
126
126
  */
127
- export function calculateDynamicThreshold(baseThreshold, trustStage, lineChanges, config) {
128
- // 1. Trust Stage multiplier
129
- const stageMultiplier = config.trust_stage_multipliers[trustStage.toString()] || 1.0;
130
- let threshold = baseThreshold * stageMultiplier;
127
+ export function calculateDynamicThreshold(baseThreshold, epTier, lineChanges, config) {
128
+ // 1. EP Tier multiplier
129
+ const tierMultiplier = config.ep_tier_multipliers[epTier.toString()] || 1.0;
130
+ let threshold = baseThreshold * tierMultiplier;
131
131
  // 2. Large scale modification reduces threshold
132
132
  if (lineChanges > config.large_change_lines) {
133
133
  const ratio = Math.min(lineChanges / 200, 0.5); // Reduce by up to 50%
@@ -91,7 +91,7 @@ Reason: ${reason}
91
91
  4. Retry the operation
92
92
 
93
93
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
94
- This is a mandatory security gate. The operation was blocked because the modification exceeds the allowed threshold for your current trust stage.
94
+ This is a mandatory security gate. The operation was blocked because the modification exceeds the allowed threshold for your current evolution tier.
95
95
  ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━`,
96
96
  };
97
97
  }
@@ -7,7 +7,7 @@
7
7
  * 2. Thinking OS Checkpoint (P-10): Deep reflection enforcement
8
8
  * 3. GFI Gate: Fatigue index-based blocking
9
9
  * 4. Bash Mutation Detection: Heuristic for bash file modifications
10
- * 5. Progressive Trust Gate: Stage 1-4 access control
10
+ * 5. Progressive Gate: EP tier-based access control
11
11
  * 6. Edit Verification (P-03): Exact/fuzzy match for edit operations
12
12
  *
13
13
  * IMPORTANT: This is the SINGLE AUTHORITATIVE orchestration path.
@@ -7,7 +7,7 @@
7
7
  * 2. Thinking OS Checkpoint (P-10): Deep reflection enforcement
8
8
  * 3. GFI Gate: Fatigue index-based blocking
9
9
  * 4. Bash Mutation Detection: Heuristic for bash file modifications
10
- * 5. Progressive Trust Gate: Stage 1-4 access control
10
+ * 5. Progressive Gate: EP tier-based access control
11
11
  * 6. Edit Verification (P-03): Exact/fuzzy match for edit operations
12
12
  *
13
13
  * IMPORTANT: This is the SINGLE AUTHORITATIVE orchestration path.
@@ -134,7 +134,7 @@ export function handleBeforeToolCall(event, ctx) {
134
134
  return progressiveGateResult;
135
135
  }
136
136
  // NOTE: Do NOT return here! Continue to edit verification.
137
- // Stage 4 bypass or Stage 1-3 allow should still run edit verification.
137
+ // All allowed operations (regardless of EP tier) should still run edit verification.
138
138
  }
139
139
  else {
140
140
  // FALLBACK: Legacy Gate Logic (when progressive gate is disabled)
@@ -4,7 +4,7 @@
4
4
  * Handles Fatigue Index (GFI) based tool blocking with TIER 0-3 classification.
5
5
  *
6
6
  * **Responsibilities:**
7
- * - Calculate dynamic GFI thresholds based on trust stage and line changes
7
+ * - Calculate dynamic GFI thresholds based on EP tier and line changes
8
8
  * - Apply tier-based tool blocking:
9
9
  * - TIER 0: Read-only tools (never blocked)
10
10
  * - TIER 1: Low-risk writes (blocked when GFI >= low_risk_block threshold)
@@ -14,7 +14,7 @@
14
14
  *
15
15
  * **Configuration:**
16
16
  * - GFI thresholds from config.gfi_gate
17
- * - Trust stage multipliers for dynamic threshold calculation
17
+ * - EP tier multipliers for dynamic threshold calculation
18
18
  * - Large change adjustments
19
19
  *
20
20
  * **Block Persistence:**
@@ -30,7 +30,7 @@ export interface GfiGateConfig {
30
30
  high_risk_block?: number;
31
31
  };
32
32
  large_change_lines?: number;
33
- trust_stage_multipliers?: Record<string, number>;
33
+ ep_tier_multipliers?: Record<string, number>;
34
34
  bash_safe_patterns?: string[];
35
35
  bash_dangerous_patterns?: string[];
36
36
  }