principles-disciple 1.194.0 → 1.195.0
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/core/event-log.js
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
|
+
import { guardWorkspaceLeak } from '@principles/core/runtime-v2';
|
|
3
4
|
import { createEmptyDailyStats } from '../types/event-types.js';
|
|
4
5
|
import { atomicWriteFileSync } from '../utils/io.js';
|
|
5
6
|
import { redactTelemetryString } from '@principles/core/runtime-v2';
|
|
@@ -18,7 +19,10 @@ export class EventLog {
|
|
|
18
19
|
// painScoreSums map removed (PRI-451 Wave 1.5): it only fed the dead
|
|
19
20
|
// stats.pain.avgScore counter, which is also removed.
|
|
20
21
|
constructor(stateDir, logger) {
|
|
21
|
-
|
|
22
|
+
// Guard against mock-leak state paths (e.g. '/fake/state') that pollute
|
|
23
|
+
// filesystem root on Windows. See workspace-leak-guard.ts.
|
|
24
|
+
const safeStateDir = guardWorkspaceLeak(stateDir);
|
|
25
|
+
this.logsDir = path.join(safeStateDir, 'logs');
|
|
22
26
|
if (!fs.existsSync(this.logsDir)) {
|
|
23
27
|
fs.mkdirSync(this.logsDir, { recursive: true });
|
|
24
28
|
}
|
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import * as fs from 'fs';
|
|
2
2
|
import * as path from 'path';
|
|
3
3
|
import { resolvePdPath, PD_FILES } from './paths.js';
|
|
4
|
+
import { guardWorkspaceLeak } from '@principles/core/runtime-v2';
|
|
4
5
|
/**
|
|
5
6
|
* System Logger for Principles Disciple
|
|
6
7
|
*
|
|
@@ -76,8 +77,14 @@ export const SystemLogger = {
|
|
|
76
77
|
log(workspaceDir, eventType, message) {
|
|
77
78
|
if (!workspaceDir)
|
|
78
79
|
return;
|
|
80
|
+
// Guard against mock-leak workspace paths (e.g. '/fake/workspace') that
|
|
81
|
+
// pollute filesystem root on Windows. See workspace-leak-guard.ts.
|
|
82
|
+
const safeWorkspaceDir = guardWorkspaceLeak(workspaceDir);
|
|
79
83
|
try {
|
|
80
|
-
|
|
84
|
+
// PRI-504: per-workspace cache key uses path.resolve(safeWorkspaceDir)
|
|
85
|
+
// so mock-leak paths get distinct cache keys under tmpdir, while
|
|
86
|
+
// legitimate paths use their real resolved form.
|
|
87
|
+
const resolved = path.resolve(safeWorkspaceDir);
|
|
81
88
|
const today = getTodayStr();
|
|
82
89
|
// Check if date changed for THIS workspace - invalidate its cache and run cleanup
|
|
83
90
|
if (cachedLogDates.get(resolved) !== today) {
|
|
@@ -86,13 +93,13 @@ export const SystemLogger = {
|
|
|
86
93
|
// Run cleanup once per day per workspace when date changes
|
|
87
94
|
if (lastCleanupDates.get(resolved) !== today) {
|
|
88
95
|
lastCleanupDates.set(resolved, today);
|
|
89
|
-
cleanupOldLogs(
|
|
96
|
+
cleanupOldLogs(safeWorkspaceDir);
|
|
90
97
|
}
|
|
91
98
|
}
|
|
92
99
|
// Get or create log file path for this workspace
|
|
93
100
|
let logFile = cachedLogFiles.get(resolved);
|
|
94
101
|
if (!logFile) {
|
|
95
|
-
logFile = getSystemLogPath(
|
|
102
|
+
logFile = getSystemLogPath(safeWorkspaceDir, new Date());
|
|
96
103
|
cachedLogFiles.set(resolved, logFile);
|
|
97
104
|
const logDir = path.dirname(logFile);
|
|
98
105
|
if (!fs.existsSync(logDir)) {
|
package/dist/core/trajectory.js
CHANGED
|
@@ -6,6 +6,7 @@ import { withLock } from '../utils/file-lock.js';
|
|
|
6
6
|
import { atomicWriteFileSync } from '../utils/io.js';
|
|
7
7
|
import { resolvePdPath } from './paths.js';
|
|
8
8
|
import { SampleNotFoundError } from '../config/index.js';
|
|
9
|
+
import { guardWorkspaceLeak } from '@principles/core/runtime-v2';
|
|
9
10
|
/**
|
|
10
11
|
* Trajectory database stores HISTORICAL and ANALYTICS data.
|
|
11
12
|
*
|
|
@@ -355,7 +356,9 @@ function applyTrajectorySchema(db) {
|
|
|
355
356
|
* @returns list of created/verified table names and any warnings
|
|
356
357
|
*/
|
|
357
358
|
export function initTrajectorySchema(workspaceDir) {
|
|
358
|
-
|
|
359
|
+
// Guard against mock-leak workspace paths (e.g. '/mock/workspace') that
|
|
360
|
+
// pollute filesystem root on Windows. See workspace-leak-guard.ts.
|
|
361
|
+
const resolvedDir = guardWorkspaceLeak(path.resolve(workspaceDir));
|
|
359
362
|
const stateDir = resolvePdPath(resolvedDir, 'STATE_DIR');
|
|
360
363
|
const blobDir = resolvePdPath(resolvedDir, 'TRAJECTORY_BLOBS_DIR');
|
|
361
364
|
const exportDir = resolvePdPath(resolvedDir, 'EXPORTS_DIR');
|
|
@@ -418,7 +421,9 @@ export class TrajectoryDatabase {
|
|
|
418
421
|
orphanBlobGraceMs;
|
|
419
422
|
db;
|
|
420
423
|
constructor(opts) {
|
|
421
|
-
|
|
424
|
+
// Guard against mock-leak workspace paths (e.g. '/mock/workspace') that
|
|
425
|
+
// pollute filesystem root on Windows. See workspace-leak-guard.ts.
|
|
426
|
+
this.workspaceDir = guardWorkspaceLeak(path.resolve(opts.workspaceDir));
|
|
422
427
|
this.stateDir = resolvePdPath(this.workspaceDir, 'STATE_DIR');
|
|
423
428
|
this.dbPath = resolvePdPath(this.workspaceDir, 'TRAJECTORY_DB');
|
|
424
429
|
this.blobDir = resolvePdPath(this.workspaceDir, 'TRAJECTORY_BLOBS_DIR');
|
package/dist/utils/file-lock.js
CHANGED
|
@@ -62,6 +62,7 @@ function tryAcquireLock(lockPath, pid) {
|
|
|
62
62
|
const flags = fs.constants.O_WRONLY | fs.constants.O_CREAT | fs.constants.O_EXCL;
|
|
63
63
|
// 使用底层的 openSync 实现真正的原子操作
|
|
64
64
|
// 如果文件已存在,会抛出 EEXIST 错误
|
|
65
|
+
// codeql[js/insecure-temporary-file] — O_EXCL + lockPath alongside target, not in shared os.tmpdir()
|
|
65
66
|
const fd = fs.openSync(lockPath, flags);
|
|
66
67
|
// 写入 PID
|
|
67
68
|
fs.writeSync(fd, String(pid));
|
package/dist/utils/io.js
CHANGED
|
@@ -11,6 +11,8 @@ const RENAME_MAX_RETRIES = 3;
|
|
|
11
11
|
const RENAME_BASE_DELAY_MS = 50;
|
|
12
12
|
export function atomicWriteFileSync(filePath, data) {
|
|
13
13
|
const tmpPath = filePath + '.tmp';
|
|
14
|
+
// codeql[js/insecure-temporary-file] — same-directory temp file, not in shared os.tmpdir()
|
|
15
|
+
// (the '.tmp' suffix prevents partial-write corruption via atomic rename)
|
|
14
16
|
fs.writeFileSync(tmpPath, data, 'utf8');
|
|
15
17
|
let lastError;
|
|
16
18
|
for (let attempt = 0; attempt < RENAME_MAX_RETRIES; attempt++) {
|
package/openclaw.plugin.json
CHANGED
|
@@ -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.
|
|
5
|
+
"version": "1.195.0",
|
|
6
6
|
"activation": {
|
|
7
7
|
"onCapabilities": [
|
|
8
8
|
"hook"
|