principles-disciple 1.7.3 → 1.7.5

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 (67) hide show
  1. package/dist/commands/evolution-status.js +4 -2
  2. package/dist/commands/focus.js +30 -155
  3. package/dist/constants/diagnostician.d.ts +16 -0
  4. package/dist/constants/diagnostician.js +60 -0
  5. package/dist/constants/tools.d.ts +2 -2
  6. package/dist/constants/tools.js +1 -1
  7. package/dist/core/config.d.ts +23 -0
  8. package/dist/core/config.js +26 -1
  9. package/dist/core/evolution-engine.js +1 -1
  10. package/dist/core/evolution-logger.d.ts +137 -0
  11. package/dist/core/evolution-logger.js +256 -0
  12. package/dist/core/evolution-reducer.d.ts +23 -0
  13. package/dist/core/evolution-reducer.js +73 -29
  14. package/dist/core/evolution-types.d.ts +6 -0
  15. package/dist/core/focus-history.d.ts +145 -0
  16. package/dist/core/focus-history.js +919 -0
  17. package/dist/core/init.js +24 -0
  18. package/dist/core/profile.js +1 -1
  19. package/dist/core/risk-calculator.d.ts +15 -0
  20. package/dist/core/risk-calculator.js +48 -0
  21. package/dist/core/trajectory.d.ts +73 -0
  22. package/dist/core/trajectory.js +206 -0
  23. package/dist/hooks/gate.js +130 -20
  24. package/dist/hooks/lifecycle.js +104 -0
  25. package/dist/hooks/pain.js +31 -0
  26. package/dist/hooks/prompt.js +136 -38
  27. package/dist/hooks/subagent.d.ts +1 -0
  28. package/dist/hooks/subagent.js +200 -18
  29. package/dist/http/principles-console-route.d.ts +7 -0
  30. package/dist/http/principles-console-route.js +301 -1
  31. package/dist/index.js +0 -2
  32. package/dist/service/central-database.d.ts +104 -0
  33. package/dist/service/central-database.js +648 -0
  34. package/dist/service/control-ui-query-service.d.ts +2 -0
  35. package/dist/service/control-ui-query-service.js +4 -0
  36. package/dist/service/empathy-observer-manager.d.ts +8 -0
  37. package/dist/service/empathy-observer-manager.js +40 -0
  38. package/dist/service/evolution-query-service.d.ts +155 -0
  39. package/dist/service/evolution-query-service.js +258 -0
  40. package/dist/service/evolution-worker.d.ts +4 -0
  41. package/dist/service/evolution-worker.js +185 -63
  42. package/dist/service/phase3-input-filter.d.ts +37 -0
  43. package/dist/service/phase3-input-filter.js +106 -0
  44. package/dist/service/runtime-summary-service.d.ts +15 -0
  45. package/dist/service/runtime-summary-service.js +111 -23
  46. package/dist/tools/deep-reflect.js +8 -2
  47. package/dist/utils/subagent-probe.d.ts +34 -0
  48. package/dist/utils/subagent-probe.js +81 -0
  49. package/openclaw.plugin.json +1 -1
  50. package/package.json +6 -4
  51. package/templates/langs/en/core/AGENTS.md +15 -3
  52. package/templates/langs/en/core/BOOTSTRAP.md +24 -1
  53. package/templates/langs/en/core/TOOLS.md +9 -0
  54. package/templates/langs/zh/core/AGENTS.md +15 -3
  55. package/templates/langs/zh/core/BOOTSTRAP.md +24 -1
  56. package/templates/langs/zh/core/TOOLS.md +9 -0
  57. package/templates/langs/zh/skills/pd-auditor/SKILL.md +61 -0
  58. package/templates/langs/zh/skills/pd-diagnostician/SKILL.md +287 -0
  59. package/templates/langs/zh/skills/pd-explorer/SKILL.md +65 -0
  60. package/templates/langs/zh/skills/pd-implementer/SKILL.md +68 -0
  61. package/templates/langs/zh/skills/pd-planner/SKILL.md +65 -0
  62. package/templates/langs/zh/skills/pd-reporter/SKILL.md +78 -0
  63. package/templates/langs/zh/skills/pd-reviewer/SKILL.md +66 -0
  64. package/dist/core/agent-loader.d.ts +0 -44
  65. package/dist/core/agent-loader.js +0 -147
  66. package/dist/tools/agent-spawn.d.ts +0 -54
  67. package/dist/tools/agent-spawn.js +0 -445
@@ -4,6 +4,7 @@ import { readPainFlagData } from '../core/pain.js';
4
4
  import { resolvePdPath } from '../core/paths.js';
5
5
  import { listSessions } from '../core/session-tracker.js';
6
6
  import { WorkspaceContext } from '../core/workspace-context.js';
7
+ import { evaluatePhase3Inputs } from './phase3-input-filter.js';
7
8
  const MAX_SOURCE_EVENTS = 5;
8
9
  const LEGACY_TRUST_REWARD_POLICY = 'frozen_all_positive';
9
10
  const GFI_PARTIAL_WARNING = 'GFI source attribution remains partial in Phase 2b because only the empathy slice is source-attributed; most non-empathy friction still lacks full per-source attribution.';
@@ -51,10 +52,11 @@ export class RuntimeSummaryService {
51
52
  const queue = this.readJsonFile(wctx.resolve('EVOLUTION_QUEUE'), warnings, false);
52
53
  const directive = this.readJsonFile(wctx.resolve('EVOLUTION_DIRECTIVE'), warnings, false);
53
54
  const queueStats = this.buildQueueStats(queue);
54
- const directiveSummary = this.buildDirectiveSummary(directive, generatedAt, warnings, queueStats);
55
+ const directiveSummary = this.buildDirectiveSummary(queue, directive, generatedAt, warnings);
55
56
  const painFlag = readPainFlagData(workspaceDir);
56
57
  const painCandidates = this.readJsonFile(wctx.resolve('PAIN_CANDIDATES'), warnings, false);
57
58
  const legacyTrust = this.readLegacyTrust(resolvePdPath(workspaceDir, 'AGENT_SCORECARD'), wctx, warnings);
59
+ const phase3Inputs = evaluatePhase3Inputs(queue ?? [], legacyTrust.phase3Input);
58
60
  const lastPainSignal = this.findLastPainSignal(events, selectedSessionId);
59
61
  const gfiSources = this.buildGfiSources(events, selectedSessionId);
60
62
  const gateStats = this.buildGateStats(events, selectedSessionId, warnings);
@@ -65,11 +67,20 @@ export class RuntimeSummaryService {
65
67
  sources: gfiSources,
66
68
  dataQuality: 'partial',
67
69
  },
68
- legacyTrust,
70
+ legacyTrust: legacyTrust.summary,
69
71
  evolution: {
70
72
  queue: queueStats,
71
73
  directive: directiveSummary,
72
- dataQuality: this.resolveEvolutionDataQuality(queue, queueStats, directiveSummary),
74
+ dataQuality: this.resolveEvolutionDataQuality(queue),
75
+ },
76
+ phase3: {
77
+ queueTruthReady: phase3Inputs.queueTruthReady,
78
+ trustInputReady: phase3Inputs.trustInputReady,
79
+ phase3ShadowEligible: phase3Inputs.phase3ShadowEligible,
80
+ evolutionEligible: phase3Inputs.evolution.eligible.length,
81
+ evolutionRejected: phase3Inputs.evolution.rejected.length,
82
+ evolutionRejectedReasons: phase3Inputs.evolution.rejected.flatMap((entry) => entry.reasons),
83
+ trustRejectedReasons: phase3Inputs.trust.rejectedReasons,
73
84
  },
74
85
  pain: {
75
86
  activeFlag: Object.keys(painFlag).length > 0,
@@ -157,8 +168,12 @@ export class RuntimeSummaryService {
157
168
  }
158
169
  return stats;
159
170
  }
160
- static buildDirectiveSummary(directive, generatedAt, warnings, queueStats) {
161
- if (!directive) {
171
+ static buildDirectiveSummary(queue, directive, generatedAt, warnings) {
172
+ const inProgressTask = this.selectInProgressTask(queue);
173
+ if (!inProgressTask) {
174
+ if (directive) {
175
+ this.warnOnLegacyDirectiveMismatch(directive, null, warnings);
176
+ }
162
177
  return {
163
178
  exists: false,
164
179
  active: null,
@@ -166,23 +181,29 @@ export class RuntimeSummaryService {
166
181
  taskPreview: null,
167
182
  };
168
183
  }
169
- const timestampMs = directive.timestamp ? new Date(directive.timestamp).getTime() : NaN;
184
+ const derivedTaskPreview = this.buildDirectiveTaskPreview(inProgressTask);
185
+ const timestampMs = this.resolveDirectiveTimestamp(inProgressTask);
170
186
  const ageSeconds = Number.isFinite(timestampMs)
171
187
  ? Math.max(0, Math.floor((new Date(generatedAt).getTime() - timestampMs) / 1000))
172
188
  : null;
173
- if (directive.active && queueStats.pending === 0 && queueStats.inProgress === 0) {
174
- warnings.push('Directive is active while the queue has no pending or in-progress task; worker state may be stale.');
189
+ if (directive) {
190
+ this.warnOnLegacyDirectiveMismatch(directive, {
191
+ active: true,
192
+ taskPreview: derivedTaskPreview,
193
+ taskId: inProgressTask.taskId ?? inProgressTask.id ?? null,
194
+ }, warnings);
175
195
  }
176
196
  return {
177
197
  exists: true,
178
- active: typeof directive.active === 'boolean' ? directive.active : null,
198
+ active: true,
179
199
  ageSeconds,
180
- taskPreview: directive.task ? directive.task.slice(0, 160) : null,
200
+ taskPreview: derivedTaskPreview,
181
201
  };
182
202
  }
183
203
  static readLegacyTrust(scorecardPath, wctx, warnings) {
184
204
  const scorecard = this.readJsonFile(scorecardPath, warnings, false);
185
205
  const score = Number.isFinite(scorecard?.trust_score) ? Number(scorecard?.trust_score) : null;
206
+ const rawFrozen = scorecard?.frozen === true ? true : false;
186
207
  const settings = wctx.config.get('trust');
187
208
  const stageThresholds = settings?.stages ?? {
188
209
  stage_1_observer: 30,
@@ -205,11 +226,18 @@ export class RuntimeSummaryService {
205
226
  }
206
227
  }
207
228
  return {
208
- score,
209
- stage,
210
- frozen: true,
211
- lastUpdated: scorecard?.last_updated ?? null,
212
- rewardPolicy: LEGACY_TRUST_REWARD_POLICY,
229
+ summary: {
230
+ score,
231
+ stage,
232
+ frozen: true,
233
+ lastUpdated: scorecard?.last_updated ?? null,
234
+ rewardPolicy: LEGACY_TRUST_REWARD_POLICY,
235
+ },
236
+ phase3Input: {
237
+ score,
238
+ frozen: rawFrozen,
239
+ lastUpdated: scorecard?.last_updated ?? null,
240
+ },
213
241
  };
214
242
  }
215
243
  static readEvents(eventsPath, warnings) {
@@ -326,16 +354,76 @@ export class RuntimeSummaryService {
326
354
  typeof entry.data?.reason === 'string' ? entry.data.reason : 'no-reason',
327
355
  ].join('::');
328
356
  }
329
- static resolveEvolutionDataQuality(queue, queueStats, directive) {
330
- if (!queue)
331
- return 'partial';
332
- if (queueStats.inProgress > 0 && (!directive.exists || directive.active !== true)) {
333
- return 'partial';
357
+ static resolveEvolutionDataQuality(queue) {
358
+ return queue ? 'authoritative' : 'partial';
359
+ }
360
+ static selectInProgressTask(queue) {
361
+ if (!queue || queue.length === 0)
362
+ return null;
363
+ const inProgress = queue.filter((item) => item?.status === 'in_progress');
364
+ if (inProgress.length === 0)
365
+ return null;
366
+ for (const item of [...inProgress].sort((a, b) => this.getQueuePriority(b) - this.getQueuePriority(a))) {
367
+ if (this.isResolvableEvolutionTask(item)) {
368
+ return item;
369
+ }
370
+ }
371
+ return null;
372
+ }
373
+ static getQueuePriority(item) {
374
+ return Number.isFinite(item.score) ? Number(item.score) : 0;
375
+ }
376
+ static isResolvableEvolutionTask(item) {
377
+ const rawTask = typeof item.task === 'string' ? item.task.trim() : '';
378
+ if (rawTask && rawTask.toLowerCase() !== 'undefined') {
379
+ return true;
380
+ }
381
+ return typeof item.id === 'string' && item.id.trim().length > 0;
382
+ }
383
+ static resolveDirectiveTimestamp(item) {
384
+ const candidate = item.started_at || item.enqueued_at || item.timestamp || null;
385
+ return candidate ? new Date(candidate).getTime() : NaN;
386
+ }
387
+ static buildDirectiveTaskPreview(item) {
388
+ const task = typeof item.task === 'string' ? item.task.trim() : '';
389
+ if (task && task.toLowerCase() !== 'undefined') {
390
+ return task.slice(0, 160);
391
+ }
392
+ const triggerTextPreview = typeof item.trigger_text_preview === 'string' ? item.trigger_text_preview.trim() : '';
393
+ const taskId = typeof item.taskId === 'string' && item.taskId.trim()
394
+ ? item.taskId.trim()
395
+ : typeof item.id === 'string' && item.id.trim()
396
+ ? item.id.trim()
397
+ : 'unknown';
398
+ const source = typeof item.source === 'string' && item.source.trim() ? item.source.trim() : 'unknown';
399
+ const reason = typeof item.reason === 'string' && item.reason.trim() ? item.reason.trim() : 'Systemic pain detected';
400
+ const preview = triggerTextPreview || 'N/A';
401
+ return `Diagnose systemic pain [ID: ${taskId}]. Source: ${source}. Reason: ${reason}. Trigger text: "${preview}"`.slice(0, 160);
402
+ }
403
+ static warnOnLegacyDirectiveMismatch(directive, derived, warnings) {
404
+ const legacyActive = typeof directive.active === 'boolean' ? directive.active : null;
405
+ const legacyTask = typeof directive.task === 'string' && directive.task.trim() ? directive.task.trim().slice(0, 160) : null;
406
+ const legacyTaskId = typeof directive.taskId === 'string' && directive.taskId.trim() ? directive.taskId.trim() : null;
407
+ const mismatchDetails = [];
408
+ if (derived === null) {
409
+ if (legacyActive === true || legacyTask || legacyTaskId) {
410
+ mismatchDetails.push('legacy directive exists but queue has no in_progress task');
411
+ }
412
+ }
413
+ else {
414
+ if (legacyActive !== null && legacyActive !== derived.active) {
415
+ mismatchDetails.push(`active=${String(legacyActive)} vs queue=${String(derived.active)}`);
416
+ }
417
+ if (legacyTask && derived.taskPreview && legacyTask !== derived.taskPreview) {
418
+ mismatchDetails.push('task text differs');
419
+ }
420
+ if (legacyTaskId && derived.taskId && legacyTaskId !== derived.taskId) {
421
+ mismatchDetails.push('task id differs');
422
+ }
334
423
  }
335
- if (directive.active && queueStats.inProgress === 0 && queueStats.pending === 0) {
336
- return 'partial';
424
+ if (mismatchDetails.length > 0) {
425
+ pushWarning(warnings, `Legacy directive file disagrees with queue-derived evolution state; queue is authoritative (${mismatchDetails.join(', ')}).`);
337
426
  }
338
- return 'authoritative';
339
427
  }
340
428
  static readJsonFile(filePath, warnings, warnOnMissing) {
341
429
  if (!fs.existsSync(filePath)) {
@@ -216,8 +216,14 @@ export function createDeepReflectTool(api) {
216
216
  });
217
217
  const startTime = Date.now();
218
218
  const subagentRuntime = api.runtime.subagent;
219
- if (!subagentRuntime)
220
- throw new Error('OpenClaw subagent runtime not found.');
219
+ if (!subagentRuntime) {
220
+ return {
221
+ content: [{
222
+ type: 'text',
223
+ text: `❌ Subagent runtime 不可用。\n\n当前运行在 embedded 模式(openclaw agent CLI),该模式不支持深反思功能。\n\n请通过 Gateway 模式运行(openclaw gateway)。`
224
+ }]
225
+ };
226
+ }
221
227
  await subagentRuntime.run({
222
228
  sessionKey,
223
229
  message: `请对我当前的任务进行深层次反思。\n\n上下文:${context}`,
@@ -0,0 +1,34 @@
1
+ /**
2
+ * Subagent Runtime Availability Probe
3
+ *
4
+ * OpenClaw has two runtime modes:
5
+ * - Gateway mode: api.runtime.subagent methods are real async functions
6
+ * - Embedded mode: api.runtime.subagent is a Proxy that throws synchronously
7
+ *
8
+ * This utility provides a reliable way to detect which mode we're in.
9
+ */
10
+ import type { OpenClawPluginApi } from '../openclaw-sdk.js';
11
+ type SubagentRuntime = NonNullable<OpenClawPluginApi['runtime']>['subagent'];
12
+ /**
13
+ * Check if the subagent runtime is actually functional.
14
+ *
15
+ * In gateway mode, subagent.run is an AsyncFunction (constructor.name === 'AsyncFunction').
16
+ * In embedded mode, subagent.run is a regular Function that throws synchronously.
17
+ *
18
+ * We use constructor check first because it's fast and has no side effects.
19
+ *
20
+ * @param subagent - The subagent runtime object from api.runtime.subagent
21
+ * @returns true if the runtime is functional (gateway mode), false otherwise
22
+ */
23
+ export declare function isSubagentRuntimeAvailable(subagent: {
24
+ run?: unknown;
25
+ } | undefined): boolean;
26
+ /**
27
+ * Get the actual subagent runtime, preferring the global gateway subagent
28
+ * if the passed one is not available.
29
+ *
30
+ * This is useful for cases where the plugin was loaded with allowGatewaySubagentBinding
31
+ * but the late-binding proxy isn't resolving correctly.
32
+ */
33
+ export declare function getAvailableSubagentRuntime(subagent: SubagentRuntime | undefined): SubagentRuntime | undefined;
34
+ export {};
@@ -0,0 +1,81 @@
1
+ /**
2
+ * Subagent Runtime Availability Probe
3
+ *
4
+ * OpenClaw has two runtime modes:
5
+ * - Gateway mode: api.runtime.subagent methods are real async functions
6
+ * - Embedded mode: api.runtime.subagent is a Proxy that throws synchronously
7
+ *
8
+ * This utility provides a reliable way to detect which mode we're in.
9
+ */
10
+ /**
11
+ * Try to access the global gateway subagent runtime.
12
+ * This is a fallback for cases where the plugin was loaded with
13
+ * allowGatewaySubagentBinding but the late-binding proxy isn't working.
14
+ */
15
+ function getGlobalGatewaySubagent() {
16
+ try {
17
+ // Access the global symbol that OpenClaw uses for gateway subagent
18
+ const symbol = Symbol.for('openclaw.plugin.gatewaySubagentRuntime');
19
+ const globalState = globalThis[symbol];
20
+ return globalState?.subagent ?? null;
21
+ }
22
+ catch {
23
+ return null;
24
+ }
25
+ }
26
+ /**
27
+ * Check if the subagent runtime is actually functional.
28
+ *
29
+ * In gateway mode, subagent.run is an AsyncFunction (constructor.name === 'AsyncFunction').
30
+ * In embedded mode, subagent.run is a regular Function that throws synchronously.
31
+ *
32
+ * We use constructor check first because it's fast and has no side effects.
33
+ *
34
+ * @param subagent - The subagent runtime object from api.runtime.subagent
35
+ * @returns true if the runtime is functional (gateway mode), false otherwise
36
+ */
37
+ export function isSubagentRuntimeAvailable(subagent) {
38
+ if (!subagent)
39
+ return false;
40
+ try {
41
+ const runFn = subagent.run;
42
+ if (typeof runFn !== 'function')
43
+ return false;
44
+ // In gateway mode, methods are AsyncFunction instances
45
+ // In embedded mode, methods are regular Function instances that throw
46
+ const isAsync = runFn.constructor?.name === 'AsyncFunction';
47
+ if (isAsync)
48
+ return true;
49
+ // Fallback: Check if it's a Proxy that might late-bind to the gateway subagent
50
+ // This handles the case where the plugin was loaded with allowGatewaySubagentBinding
51
+ // but the proxy hasn't resolved yet
52
+ const globalGateway = getGlobalGatewaySubagent();
53
+ if (globalGateway && typeof globalGateway.run === 'function') {
54
+ return globalGateway.run.constructor?.name === 'AsyncFunction';
55
+ }
56
+ return false;
57
+ }
58
+ catch {
59
+ // Any error means unavailable
60
+ return false;
61
+ }
62
+ }
63
+ /**
64
+ * Get the actual subagent runtime, preferring the global gateway subagent
65
+ * if the passed one is not available.
66
+ *
67
+ * This is useful for cases where the plugin was loaded with allowGatewaySubagentBinding
68
+ * but the late-binding proxy isn't resolving correctly.
69
+ */
70
+ export function getAvailableSubagentRuntime(subagent) {
71
+ // First check if the passed subagent is available
72
+ if (isSubagentRuntimeAvailable(subagent)) {
73
+ return subagent;
74
+ }
75
+ // Fallback to global gateway subagent
76
+ const globalGateway = getGlobalGatewaySubagent();
77
+ if (globalGateway && isSubagentRuntimeAvailable(globalGateway)) {
78
+ return globalGateway;
79
+ }
80
+ return undefined;
81
+ }
@@ -2,7 +2,7 @@
2
2
  "id": "principles-disciple",
3
3
  "name": "Principles Disciple",
4
4
  "description": "Evolutionary programming agent framework with strategic guardrails and reflection loops.",
5
- "version": "1.7.3",
5
+ "version": "1.7.4",
6
6
  "skills": [
7
7
  "./skills"
8
8
  ],
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "principles-disciple",
3
- "version": "1.7.3",
3
+ "version": "1.7.5",
4
4
  "description": "Native OpenClaw plugin for Principles Disciple",
5
5
  "type": "module",
6
6
  "main": "./dist/index.js",
@@ -8,6 +8,7 @@
8
8
  "files": [
9
9
  "dist",
10
10
  "templates",
11
+ "agents",
11
12
  "openclaw.plugin.json"
12
13
  ],
13
14
  "exports": {
@@ -35,7 +36,7 @@
35
36
  "build": "tsc",
36
37
  "build:web": "node scripts/build-web.mjs",
37
38
  "build:bundle": "node esbuild.config.js && node scripts/build-web.mjs",
38
- "build:production": "tsc && node esbuild.config.js --production && node scripts/build-web.mjs --production",
39
+ "build:production": "tsc && node esbuild.config.js --production && node scripts/build-web.mjs --production && node scripts/verify-build.mjs",
39
40
  "test": "vitest run",
40
41
  "postinstall": "node scripts/install-dependencies.cjs"
41
42
  },
@@ -49,7 +50,7 @@
49
50
  "@types/ws": "^8.5.13",
50
51
  "@vitest/coverage-v8": "^4.1.0",
51
52
  "esbuild": "^0.27.4",
52
- "jsdom": "^26.1.0",
53
+ "jsdom": "^29.0.1",
53
54
  "typescript": "^5.0.0",
54
55
  "vitest": "^4.1.0",
55
56
  "ws": "^8.18.0"
@@ -64,7 +65,8 @@
64
65
  },
65
66
  "dependencies": {
66
67
  "@sinclair/typebox": "^0.34.48",
67
- "better-sqlite3": "^11.10.0",
68
+ "better-sqlite3": "^12.8.0",
69
+ "lucide-react": "^0.468.0",
68
70
  "micromatch": "^4.0.8",
69
71
  "react": "^19.2.0",
70
72
  "react-dom": "^19.2.0",
@@ -29,10 +29,10 @@ Make decisions based on relative paths in the **Project Battlefield**:
29
29
 
30
30
  1. **Read `SOUL.md`** — confirm your identity and values
31
31
  2. **Read `USER.md`** — understand who you're helping
32
- 3. **Read `memory/YYYY-MM-DD.md`** — today's + yesterday's context
32
+ 3. **Read `memory/YYYY-MM-DD.md`** — today's + yesterday's + day-before-yesterday's context (last 3 days)
33
33
  4. **If in MAIN SESSION** (direct chat with user): Also read `MEMORY.md`
34
34
 
35
- **Don't ask permission. Just do it.**
35
+ **Don't ask permission. Just do it.** This is the key to preventing "memory loss".
36
36
 
37
37
  ---
38
38
 
@@ -45,6 +45,7 @@ You wake up fresh each session. These files are your continuity.
45
45
  - Raw logs of what happened
46
46
  - Create `memory/` if it doesn't exist
47
47
  - One file per day: decisions, context, things worth remembering
48
+ - **Auto-created**: OpenClaw's `session-memory` hook automatically creates daily memory files with conversation summaries when the user runs `/new` or `/reset`
48
49
 
49
50
  ### Long-term Memory: `MEMORY.md`
50
51
 
@@ -203,4 +204,15 @@ When completing any coding task (via AI coding assistant or direct):
203
204
  2. **Update track**: Mark task status in `conductor/tracks/*/plan.md`
204
205
  3. **Report**: Output file list + commit hash + test results
205
206
 
206
- **Why**: Context compression erases all intermediate process. Without file evidence, progress is lost.
207
+ **Why**: Context compression erases all intermediate process. Without file evidence, progress is lost.
208
+
209
+ ---
210
+
211
+ ## 🔧 Tool Routing Addendum
212
+
213
+ Use this to avoid confusing peer agents with Principles internal workers:
214
+
215
+ - **Peer agents / peer sessions**: `agents_list`, `sessions_list`, `sessions_send`, `sessions_spawn`
216
+ - **Internal workers** (for example `diagnostician`, `explorer`): use `sessions_spawn with pd-diagnostician/pd-explorer skills`
217
+ - **Inspect internal workers**: use `subagents`
218
+ - **Do not** treat `diagnostician` or `explorer` as peer session targets
@@ -102,12 +102,35 @@ Initialize the memory directory structure:
102
102
 
103
103
  ```
104
104
  memory/
105
- ├── 2026-03-12.md # Today's notes (create)
105
+ ├── YYYY-MM-DD.md # Daily notes (OpenClaw's session-memory hook auto-creates)
106
+ ├── archive/ # Historical archive (not auto-loaded)
106
107
  ├── heartbeat-state.json # Heartbeat state tracking
107
108
  └── okr/
108
109
  └── CURRENT_FOCUS.md # Current focus (if needed)
109
110
  ```
110
111
 
112
+ Also create `MEMORY.md` in the workspace root (core long-term memory):
113
+
114
+ ```markdown
115
+ # MEMORY.md - Long-term Memory
116
+
117
+ > **Last updated**: YYYY-MM-DD
118
+
119
+ ## Core Identity
120
+
121
+ [Who you are, your core mission]
122
+
123
+ ## Key Lessons
124
+
125
+ [Record important learnings to avoid repeating mistakes]
126
+
127
+ ## Recent Events
128
+
129
+ [Keep summaries of important events from the last 7 days]
130
+ ```
131
+
132
+ **Important**: `MEMORY.md` and the last 3 days of `memory/YYYY-MM-DD.md` are auto-loaded at session startup, ensuring the agent doesn't "lose context".
133
+
111
134
  ---
112
135
 
113
136
  ## Strategy Initialization (Optional)
@@ -51,3 +51,12 @@ Tool returns: Blind Spots → Risk Warnings → Alternative Approaches → Recom
51
51
  - Surfaces potential risks and failure modes
52
52
  - Provides alternative approaches with trade-off analysis
53
53
  - Applies structured thinking models for deeper insight
54
+
55
+ ---
56
+
57
+ ## 4. Agent Routing Clarification
58
+
59
+ - `agents_list`, `sessions_list`, `sessions_send`, and `sessions_spawn` are for peer agents and peer sessions
60
+ - Use `sessions_spawn` with `pd-diagnostician` or `pd-explorer` skills to start Principles internal workers
61
+ - `subagents` inspects already-started internal workers and their outputs
62
+ - Do not use peer-session tools to pretend an internal worker is a peer agent
@@ -29,10 +29,10 @@
29
29
 
30
30
  1. **Read `SOUL.md`** — 确认身份和价值观
31
31
  2. **Read `USER.md`** — 了解你在帮助谁
32
- 3. **Read `memory/YYYY-MM-DD.md`** — 今日 + 昨日的上下文
32
+ 3. **Read `memory/YYYY-MM-DD.md`** — 今日 + 昨日 + 前日的上下文(最近 3 天)
33
33
  4. **If in MAIN SESSION** (与用户的直接对话): 同时读取 `MEMORY.md`
34
34
 
35
- **不要请求许可,直接执行。**
35
+ **不要请求许可,直接执行。** 这是防止"断片"的关键。
36
36
 
37
37
  ---
38
38
 
@@ -45,6 +45,7 @@
45
45
  - 原始日志,记录发生了什么
46
46
  - 如果目录不存在,创建 `memory/`
47
47
  - 每天一个文件,记录决策、上下文、值得记住的事
48
+ - **自动创建**:OpenClaw 的 `session-memory` hook 会在用户执行 `/new` 或 `/reset` 时自动创建当日记忆文件并生成对话摘要
48
49
 
49
50
  ### 长期记忆:`MEMORY.md`
50
51
 
@@ -204,4 +205,15 @@ _This folder is home. Treat it that way._
204
205
  2. **更新 track**:在 `conductor/tracks/*/plan.md` 中标记任务状态
205
206
  3. **输出报告**:修改文件列表 + commit hash + 测试结果
206
207
 
207
- **原因**:上下文压缩会丢失所有中间过程。没有文件证据,进度就会丢失。
208
+ **原因**:上下文压缩会丢失所有中间过程。没有文件证据,进度就会丢失。
209
+
210
+ ---
211
+
212
+ ## 🔧 工具路由补充说明
213
+
214
+ 用下面这几条避免把同级代理和 Principles 内部 worker 混淆:
215
+
216
+ - **同级代理 / 同级会话**:`agents_list`、`sessions_list`、`sessions_send`、`sessions_spawn`
217
+ - **内部 worker**(例如 `diagnostician`、`explorer`):使用 `sessions_spawn` 配合 `pd-diagnostician/pd-explorer` skill 启动
218
+ - **查询内部 worker**:使用 `subagents`
219
+ - **不要**把 `diagnostician` 或 `explorer` 当成同级 peer session 目标
@@ -102,12 +102,35 @@ tree -L 2 # 查看目录树(如果可用)
102
102
 
103
103
  ```
104
104
  memory/
105
- ├── 2026-03-12.md # 今日笔记(创建)
105
+ ├── YYYY-MM-DD.md # 每日笔记(OpenClaw 的 session-memory hook 会自动创建)
106
+ ├── archive/ # 历史归档(不自动加载)
106
107
  ├── heartbeat-state.json # 心跳状态追踪
107
108
  └── okr/
108
109
  └── CURRENT_FOCUS.md # 当前焦点(如果需要)
109
110
  ```
110
111
 
112
+ 同时在 workspace 根目录创建 `MEMORY.md`(核心长期记忆):
113
+
114
+ ```markdown
115
+ # MEMORY.md - 长期记忆
116
+
117
+ > **最后更新**: YYYY-MM-DD
118
+
119
+ ## 核心定位
120
+
121
+ [你是谁,你的核心使命]
122
+
123
+ ## 关键教训
124
+
125
+ [记录重要的学习成果,避免重复犯错]
126
+
127
+ ## 近期事件
128
+
129
+ [保留最近 7 天的重要事件摘要]
130
+ ```
131
+
132
+ **重要**:`MEMORY.md` 和最近 3 天的 `memory/YYYY-MM-DD.md` 会在每次会话启动时自动加载,确保智能体不会"断片"。
133
+
111
134
  ---
112
135
 
113
136
  ## 战略初始化(可选)
@@ -51,3 +51,12 @@ deep_reflect(
51
51
  工具返回:盲点分析 → 风险警告 → 替代方案 → 建议 → 置信度
52
52
 
53
53
  **注意**:这是批判性反馈,最终决策权在你。认真考虑建议,但不必盲目遵循。
54
+
55
+ ---
56
+
57
+ ## 4. 智能体路由澄清
58
+
59
+ - `agents_list`、`sessions_list`、`sessions_send`、`sessions_spawn` 用于同级代理和同级会话
60
+ - 使用 `sessions_spawn` 配合 `pd-diagnostician/pd-explorer` skill 启动 Principles 内部 worker,例如 `diagnostician`、`explorer`
61
+ - `subagents` 用于查看已启动内部 worker 的状态和输出
62
+ - 不要用同级会话工具把内部 worker 伪装成同级代理
@@ -0,0 +1,61 @@
1
+ ---
2
+ name: pd-auditor
3
+ description: 演绎审计智能体。使用公理验证、系统审计、否定论证方法验证系统一致性。当需要审计系统或流程时使用。
4
+ disable-model-invocation: true
5
+ ---
6
+
7
+ # Auditor
8
+
9
+ 你是严谨的演绎审计专家。你的任务是使用结构化的推理方法验证系统的一致性。
10
+
11
+ ## 审计方法
12
+
13
+ 使用三阶段审计框架:
14
+
15
+ ### 阶段 1: 公理验证 (Axiom Verification)
16
+ - 检查系统是否遵循基础公理
17
+ - 验证核心假设是否自洽
18
+ - 识别逻辑矛盾
19
+
20
+ ### 阶段 2: 系统审计 (System Audit)
21
+ - 检查组件间的交互是否正确
22
+ - 验证数据流和控制流
23
+ - 识别设计缺陷
24
+
25
+ ### 阶段 3: 否定论证 (Via Negativa)
26
+ - 系统地排除"不可能的"选项
27
+ - 通过排除错误路径逼近真相
28
+ - 验证必需条件的满足
29
+
30
+ ## 输出格式
31
+
32
+ ### 审计报告
33
+
34
+ **审计目标**: [明确的审计对象]
35
+
36
+ **公理验证**:
37
+ - [公理1]: [验证结果]
38
+ - [公理2]: [验证结果]
39
+
40
+ **系统审计**:
41
+ - [组件A]: [发现的问题]
42
+ - [组件B]: [发现的问题]
43
+
44
+ **否定论证**:
45
+ - 排除假设1: [为什么不可能]
46
+ - 排除假设2: [为什么不可能]
47
+
48
+ **审计结论**: [综合判断]
49
+
50
+ **风险评级**: 低|中|高
51
+
52
+ ## 注意事项
53
+
54
+ - 每个审计点都应该有明确的判断依据
55
+ - 不要跳跃式推理,逐步展开
56
+ - 如果信息不足,明确说明需要什么
57
+ - 结论要可验证,而非直觉判断
58
+
59
+ ---
60
+
61
+ 请按照这个框架进行审计,输出结构化的验证报告。