evolcore 0.0.33 → 0.0.34
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/CHANGELOG.md +37 -0
- package/bin/ec.js +3 -2
- package/bin/install-codex-managed-hooks.mjs +12 -1
- package/dist/agents/baseagent-availability.js +20 -36
- package/dist/agents/claude-runner.js +82 -13
- package/dist/agents/codex/diagnostics.js +37 -11
- package/dist/agents/codex-runner.js +218 -44
- package/dist/agents/ecagent-runner.js +73 -20
- package/dist/agents/runner-types.js +5 -6
- package/dist/aun/aid/identity.js +1 -1
- package/dist/channels/aun.js +16 -6
- package/dist/channels/daemon.js +6 -3
- package/dist/cli/aun-commands.js +3 -2
- package/dist/cli/ctl-command.js +3 -1
- package/dist/cli/daemon-commands.js +120 -19
- package/dist/cli/fs-command.js +2 -1
- package/dist/cli/index.js +20 -6
- package/dist/cli/integrity-command.js +196 -0
- package/dist/cli/memory-command.js +158 -145
- package/dist/cli/thread-command.js +5 -3
- package/dist/cli/trigger-command.js +6 -1
- package/dist/config/config-field-policy.js +4 -0
- package/dist/config/config-manager.js +19 -0
- package/dist/config/contact-book-store.js +5 -0
- package/dist/config/role-service.js +13 -0
- package/dist/config/runtime-env.js +16 -0
- package/dist/config-store.js +30 -0
- package/dist/core/audit/log-integrity.js +3 -1
- package/dist/core/auth/agent-delegation.js +108 -35
- package/dist/core/auth/delegation-diagnostics.js +414 -0
- package/dist/core/auth/operation-authorizer.js +1 -1
- package/dist/core/auth/operation-catalog.js +16 -0
- package/dist/core/command/agent-control.js +18 -26
- package/dist/core/command/command-handler.js +138 -4
- package/dist/core/command/daemon-diagnostics.js +1 -0
- package/dist/core/command/menu-catalog.js +3 -0
- package/dist/core/command/menu-handler.js +22 -7
- package/dist/core/command/menu-protocol.js +1 -0
- package/dist/core/command/slash-handler.js +2 -0
- package/dist/core/daemon-bootstrap.js +4 -7
- package/dist/core/file-integrity/read.js +61 -0
- package/dist/core/file-integrity/store.js +262 -0
- package/dist/core/ipc-registration.js +36 -1
- package/dist/core/memory/batch-meta.js +132 -0
- package/dist/core/memory/consolidation-context.js +35 -14
- package/dist/core/memory/consolidation-ops-records.js +14 -16
- package/dist/core/memory/consolidation.js +91 -26
- package/dist/core/memory/index-manager.js +19 -28
- package/dist/core/memory/memory-admin.js +19 -14
- package/dist/core/memory/memory-document.js +53 -9
- package/dist/core/memory/memory-writer.js +30 -15
- package/dist/core/message/im-renderer.js +20 -4
- package/dist/core/message/message-bridge.js +2 -1
- package/dist/core/message/response-engine.js +584 -47
- package/dist/core/permission/ec-command-parser.js +93 -4
- package/dist/core/permission/protected-paths.js +5 -1
- package/dist/core/permission/readonly-shell-query.js +43 -5
- package/dist/core/permission/session-path-grants.js +334 -0
- package/dist/core/permission/tool-canonical.js +226 -0
- package/dist/core/permission/tool-policy.js +30 -62
- package/dist/core/role/runtime-policy.js +21 -10
- package/dist/core/session/session-fs-store.js +123 -8
- package/dist/core/session/session-manager.js +75 -5
- package/dist/core/skill/index-generator.js +17 -3
- package/dist/core/system-session/grants.js +40 -0
- package/dist/core/system-session/memory.js +222 -0
- package/dist/core/system-session/registry.js +74 -0
- package/dist/core/system-session/types.js +14 -0
- package/dist/core/thread/thread-service.js +13 -20
- package/dist/eck/kit-renderer.js +7 -2
- package/dist/eck/manifest-engine.js +24 -4
- package/dist/index.js +11 -2
- package/dist/ipc.js +51 -40
- package/dist/paths.js +70 -0
- package/dist/stats/billing.js +20 -8
- package/dist/trigger/feedback.js +6 -1
- package/dist/trigger/parser.js +8 -1
- package/dist/trigger/system-definitions.js +3 -3
- package/dist/utils/cross-platform.js +11 -2
- package/dist/utils/error-dict.json +18 -4
- package/dist/utils/error-utils.js +121 -0
- package/dist/utils/instance-registry.js +13 -8
- package/dist/utils/log-writer.js +12 -0
- package/dist/utils/process-introspect.js +11 -0
- package/kits/docs/context-assembly.md +0 -1
- package/kits/docs/evolcore/agent-create.md +5 -4
- package/kits/docs/evolcore/agent.md +2 -2
- package/kits/docs/evolcore/config.md +2 -2
- package/kits/docs/evolcore/ctl.md +2 -2
- package/kits/docs/evolcore/ec-capabilities.md +1 -1
- package/kits/docs/evolcore/fs-architecture.md +4 -5
- package/kits/docs/evolcore/fs.md +1 -1
- package/kits/docs/evolcore/group-collaboration.md +2 -2
- package/kits/docs/evolcore/group.md +10 -10
- package/kits/docs/evolcore/memory-architecture.md +4 -5
- package/kits/docs/evolcore/memory-consolidation.md +18 -14
- package/kits/docs/evolcore/memory-tags.md +3 -1
- package/kits/docs/evolcore/memory.md +24 -12
- package/kits/docs/evolcore/model.md +16 -0
- package/kits/docs/evolcore/msg.md +7 -7
- package/kits/docs/evolcore/thread-chain.md +5 -5
- package/kits/docs/prompt-loading-architecture.md +0 -1
- package/kits/eck_manifest.json +0 -20
- package/kits/eck_manifest.memory.json +0 -12
- package/kits/rules/01-overview.md +11 -0
- package/kits/rules/03-identity.md +6 -3
- package/kits/rules/06-channel.md +1 -1
- package/kits/rules/07-memory-and-thread.md +12 -15
- package/kits/schemas/_meta.json +7 -1
- package/kits/schemas/agent-config.schema.13.json +1 -1
- package/kits/schemas/daemon.schema.7.json +140 -0
- package/kits/skills/ec-group/SKILL.md +4 -4
- package/kits/skills/ec-skill/scripts/cli.mjs +1 -1
- package/kits/skills/ec-skill/scripts/skill.mjs +1 -1
- package/kits/templates/memory-consolidation/forget.md +2 -2
- package/kits/templates/memory-consolidation/generalize.md +4 -4
- package/kits/templates/memory-consolidation/notes.md +11 -11
- package/kits/templates/memory-consolidation/profile.md +3 -3
- package/kits/templates/memory-consolidation/promote.md +3 -3
- package/kits/templates/memory-consolidation/workflow.md +6 -6
- package/kits/templates/message-fragments/handoff-request-to-target.md +1 -1
- package/kits/templates/system-fragments/bootstrap.md +4 -3
- package/kits/templates/system-fragments/channel.md +2 -2
- package/kits/templates/system-fragments/memory.md +16 -9
- package/kits/templates/system-fragments/reply.md +6 -6
- package/kits/templates/system-fragments/session.md +1 -1
- package/package.json +4 -3
- package/dist/core/memory/memory-session-policy.js +0 -41
- package/dist/core/memory/memory-signature.js +0 -257
|
@@ -91,6 +91,117 @@ export var ErrorType;
|
|
|
91
91
|
ErrorType["CLAUDE_CODE_STARTUP_FAILED"] = "claude_code_startup_failed";
|
|
92
92
|
ErrorType["UNKNOWN"] = "unknown";
|
|
93
93
|
})(ErrorType || (ErrorType = {}));
|
|
94
|
+
export function getErrorRawText(error, seen = new Set()) {
|
|
95
|
+
if (typeof error === 'string') {
|
|
96
|
+
const text = error.trim();
|
|
97
|
+
return text || undefined;
|
|
98
|
+
}
|
|
99
|
+
if (error === null || error === undefined)
|
|
100
|
+
return undefined;
|
|
101
|
+
if (typeof error === 'object') {
|
|
102
|
+
const record = error;
|
|
103
|
+
if (seen.has(error))
|
|
104
|
+
return undefined;
|
|
105
|
+
seen.add(error);
|
|
106
|
+
if ('raw' in record) {
|
|
107
|
+
const raw = record.raw;
|
|
108
|
+
if (typeof raw === 'string' && raw.trim())
|
|
109
|
+
return raw.trim();
|
|
110
|
+
}
|
|
111
|
+
const causeText = getErrorRawText(record.cause, seen);
|
|
112
|
+
if (causeText)
|
|
113
|
+
return causeText;
|
|
114
|
+
for (const key of ['message', 'error', 'reason']) {
|
|
115
|
+
const value = record[key];
|
|
116
|
+
if (typeof value === 'string' && value.trim())
|
|
117
|
+
return value.trim();
|
|
118
|
+
if (value && typeof value === 'object') {
|
|
119
|
+
const nestedText = getErrorRawText(value, seen);
|
|
120
|
+
if (nestedText)
|
|
121
|
+
return nestedText;
|
|
122
|
+
}
|
|
123
|
+
}
|
|
124
|
+
const code = record.code;
|
|
125
|
+
if (typeof code === 'string' && code.trim())
|
|
126
|
+
return code.trim();
|
|
127
|
+
return undefined;
|
|
128
|
+
}
|
|
129
|
+
const text = String(error).trim();
|
|
130
|
+
return text || undefined;
|
|
131
|
+
}
|
|
132
|
+
export function normalizeCoreErrorSubtype(error, reportedSubtype, terminalReason) {
|
|
133
|
+
const reported = reportedSubtype?.trim().toLowerCase();
|
|
134
|
+
if (error instanceof OrphanedTargetSessionError)
|
|
135
|
+
return ErrorType.SESSION_UNAVAILABLE;
|
|
136
|
+
if (error instanceof ExecutionTimeoutError)
|
|
137
|
+
return ErrorType.SDK_TIMEOUT;
|
|
138
|
+
if (terminalReason === 'prompt_too_long' || terminalReason === 'context_compact_failed') {
|
|
139
|
+
return ErrorType.CONTEXT_TOO_LONG;
|
|
140
|
+
}
|
|
141
|
+
if (terminalReason === 'max_output_tokens')
|
|
142
|
+
return ErrorType.MAX_OUTPUT_TOKENS;
|
|
143
|
+
if (terminalReason === 'model_error')
|
|
144
|
+
return ErrorType.MODEL_UNAVAILABLE;
|
|
145
|
+
if (terminalReason === 'permission_denied')
|
|
146
|
+
return 'permission_error';
|
|
147
|
+
if (terminalReason === 'timeout' || terminalReason === 'total_execution_timeout')
|
|
148
|
+
return ErrorType.SDK_TIMEOUT;
|
|
149
|
+
if (reported === 'protocol_incomplete')
|
|
150
|
+
return 'protocol_incomplete';
|
|
151
|
+
if (reported === 'permission_denied' || reported?.startsWith('permission_'))
|
|
152
|
+
return 'permission_error';
|
|
153
|
+
const classified = classifyError(typeof error === 'string' ? new Error(error) : error);
|
|
154
|
+
if (classified !== ErrorType.UNKNOWN)
|
|
155
|
+
return classified;
|
|
156
|
+
if (reported && Object.values(ErrorType).includes(reported))
|
|
157
|
+
return reported;
|
|
158
|
+
switch (reported) {
|
|
159
|
+
case 'error_api':
|
|
160
|
+
case 'api':
|
|
161
|
+
case 'infrastructure':
|
|
162
|
+
return ErrorType.API_ERROR;
|
|
163
|
+
case 'error_model':
|
|
164
|
+
case 'model_error':
|
|
165
|
+
return ErrorType.MODEL_UNAVAILABLE;
|
|
166
|
+
case 'error_tool_use':
|
|
167
|
+
case 'tool_error':
|
|
168
|
+
return ErrorType.STREAM_ERROR;
|
|
169
|
+
}
|
|
170
|
+
if (terminalReason === 'rapid_refill_breaker')
|
|
171
|
+
return ErrorType.API_ERROR;
|
|
172
|
+
if (terminalReason === 'tool_error')
|
|
173
|
+
return ErrorType.STREAM_ERROR;
|
|
174
|
+
if (reported)
|
|
175
|
+
return reported;
|
|
176
|
+
return ErrorType.UNKNOWN;
|
|
177
|
+
}
|
|
178
|
+
export function normalizeCoreErrorReason(reason) {
|
|
179
|
+
const normalized = reason?.trim().toLowerCase();
|
|
180
|
+
switch (normalized) {
|
|
181
|
+
case 'retry.exhausted':
|
|
182
|
+
return 'retry_exhausted';
|
|
183
|
+
case 'sdk_timeout':
|
|
184
|
+
case 'total_execution_timeout':
|
|
185
|
+
return 'timeout';
|
|
186
|
+
case 'aborted_streaming':
|
|
187
|
+
case 'aborted_tools':
|
|
188
|
+
case 'stop':
|
|
189
|
+
return 'cancelled';
|
|
190
|
+
case 'protocol_incomplete':
|
|
191
|
+
case 'max_output_tokens':
|
|
192
|
+
case 'target_session_timeout':
|
|
193
|
+
case 'retry_exhausted':
|
|
194
|
+
case 'timeout':
|
|
195
|
+
case 'cancelled':
|
|
196
|
+
case 'permission_denied':
|
|
197
|
+
case 'input_already_submitted':
|
|
198
|
+
case 'fallback_exhausted':
|
|
199
|
+
case 'orphaned_target_session':
|
|
200
|
+
return normalized;
|
|
201
|
+
default:
|
|
202
|
+
return undefined;
|
|
203
|
+
}
|
|
204
|
+
}
|
|
94
205
|
/**
|
|
95
206
|
* 错误来源前缀 — 区分基础设施异常 vs Agent 任务失败
|
|
96
207
|
*
|
|
@@ -516,6 +627,16 @@ export function getErrorMessage(error, terminalReason, includeEmoji = true) {
|
|
|
516
627
|
return `${errPrefix}暂无法判定错误原因:${msg}`;
|
|
517
628
|
return `${errPrefix}处理消息时出错,请稍后重试`;
|
|
518
629
|
}
|
|
630
|
+
export function getToolResultErrorText(event) {
|
|
631
|
+
const text = event.error || event.reason
|
|
632
|
+
|| (event.name === 'Shell'
|
|
633
|
+
? typeof event.exitCode === 'number' && Number.isInteger(event.exitCode)
|
|
634
|
+
? 'exitCode: ' + event.exitCode
|
|
635
|
+
: '执行失败'
|
|
636
|
+
: typeof event.result === 'string' ? event.result : JSON.stringify(event.result))
|
|
637
|
+
|| '执行失败';
|
|
638
|
+
return text.replace(/<tool_use_error>(.*?)<\/tool_use_error>/gs, '$1');
|
|
639
|
+
}
|
|
519
640
|
function resolveErrorMessage(error) {
|
|
520
641
|
if (typeof error === 'string')
|
|
521
642
|
return error.trim();
|
|
@@ -11,8 +11,8 @@
|
|
|
11
11
|
import fs from 'fs';
|
|
12
12
|
import path from 'path';
|
|
13
13
|
import { spawnSync } from 'child_process';
|
|
14
|
-
import { getPackageRoot, resolvePaths } from '../paths.js';
|
|
15
|
-
import { isProcessRunning, killProcess, isWindows,
|
|
14
|
+
import { getPackageRoot, resolvePaths, isDevMode } from '../paths.js';
|
|
15
|
+
import { isProcessRunning, killProcess, isWindows, findProcessesWithCommandLine } from './cross-platform.js';
|
|
16
16
|
import { getProcessStartTime, startTimeMatches } from './process-introspect.js';
|
|
17
17
|
import { isConfirmedLeakedTestDaemon, runtimeHomeFromEnv } from './restart-safety.js';
|
|
18
18
|
import { decodeWindowsOutput } from './windows-output.js';
|
|
@@ -55,6 +55,7 @@ export function writeMain(launchedBy) {
|
|
|
55
55
|
startedAt,
|
|
56
56
|
startedAtIso: new Date(startedAt).toISOString(),
|
|
57
57
|
launchedBy,
|
|
58
|
+
runMode: isDevMode() ? 'dev' : 'install',
|
|
58
59
|
};
|
|
59
60
|
const filePath = path.join(dir, mainFileName(process.pid));
|
|
60
61
|
writeAtomic(filePath, JSON.stringify(record, null, 2));
|
|
@@ -376,10 +377,10 @@ export function isEvolCoreMainCommand(cmdline, packageRoot = getPackageRoot()) {
|
|
|
376
377
|
*
|
|
377
378
|
* 不会主动 kill——清理由调用方决定。
|
|
378
379
|
*/
|
|
379
|
-
export function findOrphanProcesses() {
|
|
380
|
-
// 1. 已登记 PID(自己 HOME 下的 main +
|
|
380
|
+
export function findOrphanProcesses(status = scanInstances()) {
|
|
381
|
+
// 1. 已登记 PID(自己 HOME 下的 main + 自己进程)。调用方刚扫过登记簿时可直接传入,
|
|
382
|
+
// Windows 上每次 scanInstances 都要为活实例跑一遍 CIM 查询。
|
|
381
383
|
const known = new Set([process.pid]);
|
|
382
|
-
const status = scanInstances();
|
|
383
384
|
for (const m of status.mains) {
|
|
384
385
|
if (m.alive)
|
|
385
386
|
known.add(m.record.pid);
|
|
@@ -393,14 +394,18 @@ export function findOrphanProcesses() {
|
|
|
393
394
|
// regex contains escaped separators and is applied after command lines have
|
|
394
395
|
// been fetched; embedding it in the CIM pre-filter can silently miss a
|
|
395
396
|
// backslash-delimited `dist\\index.js` command on some PowerShell builds.
|
|
396
|
-
|
|
397
|
+
// `index.js` 会命中所有 Node 服务(各会话拉起的 MCP server 常有十几个),
|
|
398
|
+
// 所以先用快照里的命令行过滤,只对真正的 EvolCore 入口做后续探测。
|
|
399
|
+
const candidates = findProcessesWithCommandLine('index\\.js');
|
|
397
400
|
const orphans = [];
|
|
398
|
-
for (const pid of candidates) {
|
|
401
|
+
for (const { pid, commandLine } of candidates) {
|
|
399
402
|
if (known.has(pid))
|
|
400
403
|
continue;
|
|
404
|
+
if (commandLine !== undefined && !isEvolCoreMainCommand(commandLine))
|
|
405
|
+
continue;
|
|
401
406
|
if (!isProcessRunning(pid))
|
|
402
407
|
continue;
|
|
403
|
-
const cmdline = readCmdline(pid);
|
|
408
|
+
const cmdline = commandLine || readCmdline(pid);
|
|
404
409
|
// 二次验证:入口必须是当前 EvolCore 包的 dist/index.js。
|
|
405
410
|
if (!isEvolCoreMainCommand(cmdline))
|
|
406
411
|
continue;
|
package/dist/utils/log-writer.js
CHANGED
|
@@ -122,6 +122,18 @@ export class LogWriter {
|
|
|
122
122
|
// 写入失败不抛——日志不能影响业务
|
|
123
123
|
}
|
|
124
124
|
}
|
|
125
|
+
writeChecked(line) {
|
|
126
|
+
this.rotateIfNeeded(false);
|
|
127
|
+
const filePath = this.activePath();
|
|
128
|
+
const descriptor = fs.openSync(filePath, fs.constants.O_APPEND | fs.constants.O_CREAT | fs.constants.O_WRONLY | (fs.constants.O_NOFOLLOW ?? 0), 0o600);
|
|
129
|
+
try {
|
|
130
|
+
fs.fchmodSync(descriptor, 0o600);
|
|
131
|
+
fs.writeFileSync(descriptor, line + '\n');
|
|
132
|
+
}
|
|
133
|
+
finally {
|
|
134
|
+
fs.closeSync(descriptor);
|
|
135
|
+
}
|
|
136
|
+
}
|
|
125
137
|
/** 关闭(停掉清理 timer)。一般不需要调用,进程退出 timer 自动失效 */
|
|
126
138
|
close() {
|
|
127
139
|
if (this.boundaryTimer) {
|
|
@@ -29,11 +29,22 @@ function readLinuxClockTicks() {
|
|
|
29
29
|
const linuxClockTicks = readLinuxClockTicks();
|
|
30
30
|
/** 容差:2 秒(覆盖 macOS 秒级精度 + 时钟漂移) */
|
|
31
31
|
export const START_TIME_TOLERANCE_MS = 2000;
|
|
32
|
+
/** 本进程的启动时间不会变;Windows 上每次查询都要拉起一次 PowerShell(约 0.4s)。 */
|
|
33
|
+
let selfStartTime = null;
|
|
32
34
|
/**
|
|
33
35
|
* 获取进程启动时间(Unix 毫秒)。
|
|
34
36
|
* 拿不到时返回 null,调用方应保守处理(不杀该 PID)。
|
|
35
37
|
*/
|
|
36
38
|
export function getProcessStartTime(pid) {
|
|
39
|
+
if (pid === process.pid) {
|
|
40
|
+
// 只缓存成功结果,一次探测失败不会让后续调用永久拿到 null。
|
|
41
|
+
if (selfStartTime === null)
|
|
42
|
+
selfStartTime = readProcessStartTime(pid);
|
|
43
|
+
return selfStartTime;
|
|
44
|
+
}
|
|
45
|
+
return readProcessStartTime(pid);
|
|
46
|
+
}
|
|
47
|
+
function readProcessStartTime(pid) {
|
|
37
48
|
try {
|
|
38
49
|
if (isWindows)
|
|
39
50
|
return getStartTimeWindows(pid);
|
|
@@ -295,7 +295,6 @@ coding 场景(无 channel/无身份)下,`chatType`、`channel`、`selfAid`
|
|
|
295
295
|
| 15 | bootstrap-guide | `bootstrap.md` | lifecycle=bootstrapping | ✓ |
|
|
296
296
|
| 20 | identity-layer | fragment | active 且 chatType≠null | ✓ |
|
|
297
297
|
| 21 | persona | `$PERSONAL_DIR/persona.md` | active 且 chatType≠null | ✗ |
|
|
298
|
-
| 21.5 | personal-profile | `$PERSONAL_DIR/personal.md` | active 且 chatType≠null | ✗ |
|
|
299
298
|
| 30 | relation-layer | fragment | active 且 chatType∈{private,group} | ✓ |
|
|
300
299
|
| 35 | memory | `$KITS_FRAGMENTS/memory.md` | active 且 memoryEnableRelation≠false | ✓ |
|
|
301
300
|
| 36 | agent-memory | `$PERSONAL_DIR/memory/MEMORY.md` | active 且 memoryEnableAgent≠false | ✗ |
|
|
@@ -161,12 +161,13 @@ Bootstrap 完成前,新 Agent 不处理普通任务,也不执行与本流程
|
|
|
161
161
|
- 只修改 `name`、`description`、`tags`,不改其它 frontmatter 字段或正文。
|
|
162
162
|
- 名片文件位于受保护路径,用文件工具直接读写会被拒绝;`set` 命令会自己写回并签名。
|
|
163
163
|
|
|
164
|
-
对话式 Bootstrap 中,新 Agent 还要在 `$PERSONAL_DIR/
|
|
164
|
+
对话式 Bootstrap 中,新 Agent 还要在 `$PERSONAL_DIR/persona.md` 中写入交接摘要(一次性 `--initialize` 模式不经过这段对话,也不会自动生成此摘要):
|
|
165
165
|
|
|
166
166
|
- 忠实整理 Owner 已明确提供或已认可的职责、协作边界、重要约束和激活后待继续事项,不新增推断或约定;此内部交接不要求 Owner 审稿,确有职责歧义才澄清设定本身。待继续事项标注“未执行”,不启动任务或设置自动触发。
|
|
167
167
|
- 没有额外约束或待继续事项时省略相应条目,仍保存已明确的职责,不为补齐摘要增加追问。
|
|
168
168
|
- 不复制完整 Bootstrap 历史、临时闲聊、凭据、运行状态或未确认推断;此文件会进入后续私聊和群聊上下文,不写 Owner 的私密信息。
|
|
169
|
-
- 文件不存在时创建;已有文件只新增或幂等更新 `## Bootstrap 交接`
|
|
169
|
+
- 文件不存在时创建;已有文件只新增或幂等更新 `## Bootstrap 交接` 段落,**保留其它段落**(尤其是 Owner 已设定的人格内容)。
|
|
170
|
+
- 写这一段用文件工具直接编辑 `persona.md`(Owner 会话中该文件可写);不要用 `ec agent persona --text` 只写交接段——那是整体覆盖。要整体设置人格时才用 `ec agent persona --text '<完整内容>'`。
|
|
170
171
|
- 交接摘要保存失败时不得执行 `ready`;不要把摘要整理变成名片确认后的另一轮确认。
|
|
171
172
|
|
|
172
173
|
## 5. Agent 自主准备正式欢迎文案并发布名片
|
|
@@ -208,7 +209,7 @@ ec agent ready helper.agentid.pub
|
|
|
208
209
|
3. 为每位 Owner 创建全新的主会话。
|
|
209
210
|
4. 向全部 Owner 发送正式欢迎消息,并为各 Owner 绑定对应的新会话。
|
|
210
211
|
|
|
211
|
-
新主会话会在文件存在时自动注入 `$PERSONAL_DIR/
|
|
212
|
+
新主会话会在文件存在时自动注入 `$PERSONAL_DIR/persona.md`。新 Agent 首次回复前,应先阅读其中的 `## Bootstrap 交接`,沿用已确认的职责和约定;仅对标注为未执行的事项按正常权限继续沟通,不把它们误称为已经完成。这个方案由新 Agent 在 `ready` 前写入摘要,不是系统自动复制或总结旧 Bootstrap 历史,会话切换机制保持不变。
|
|
212
213
|
|
|
213
214
|
新 Agent 在 `ready` 成功后不要从旧 Bootstrap 上下文再输出一段完成说明,也不要继续处理先前夹带的普通任务;后续工作从新主会话开始。
|
|
214
215
|
|
|
@@ -236,7 +237,7 @@ Bootstrap 首条消息只发送给 `owners[0]`;`ready` 成功后,正式欢
|
|
|
236
237
|
- 本地与远端 `agent.md` 的 `name`、`description`、`tags` 与 Owner 明确提供或已认可的值一致;创建流程 skill 必须在发布后复读核验,不以初始上传响应代替。
|
|
237
238
|
- 如果 Owner 选择提供头像,远端 `agent.md` 的 `avatar` 已更新并发布;未提供时跳过,已明确提供但规范化或上传失败时创建进入可恢复失败状态。
|
|
238
239
|
- 对话式 Bootstrap:`personal/welcome.md` 已保存 Agent 自主准备的完整正式文案;Owner 未被要求起草、审稿或确认,投递使用已保存正文。
|
|
239
|
-
- 对话式 Bootstrap:`personal/
|
|
240
|
+
- 对话式 Bootstrap:`personal/persona.md` 包含忠实整理明确职责和约定的 `## Bootstrap 交接` 摘要;待继续事项标注“未执行”,未确认的设定推断、完整历史和临时运行状态没有写入。
|
|
240
241
|
- 系统已创建新的主会话并发送正式欢迎消息。
|
|
241
242
|
- 新 Agent 能在新主会话中处理普通任务。
|
|
242
243
|
|
|
@@ -66,7 +66,7 @@ ec agent welcome show
|
|
|
66
66
|
ec agent welcome --text '<完整 Markdown 文案>'
|
|
67
67
|
|
|
68
68
|
# 修改 agent.md 显示名称
|
|
69
|
-
ec agent rename <aid>
|
|
69
|
+
ec agent rename <aid> '<name>'
|
|
70
70
|
|
|
71
71
|
# 标记 bootstrap 完成,进入 active 状态
|
|
72
72
|
ec agent ready <aid>
|
|
@@ -97,7 +97,7 @@ ec agent delete <aid> [--purge]
|
|
|
97
97
|
- `ec agent welcome --text <text>` 用于保存 Bootstrap 中 Agent 自主准备的完整正式文案,不要求 Owner 起草、审稿或确认;命令固定写入当前 Agent 的 `$PERSONAL_DIR/welcome.md`,不接受自定义路径。`welcome show` 读取该文件。
|
|
98
98
|
- welcome 托管写入要求当前 Agent 私聊 Owner;admin 仅可读。模板上限 4 KiB,渲染上限 8 KiB;变量为 `agentName`、`agentDescription`、`agentAid`、`agentTags`、`agentTagsText`、`ownerName`、`ownerAid`、`channel`,支持标签循环和真值条件。写入保留原始文本,投递不附加额外文案。
|
|
99
99
|
- `agent show <target-aid>` 与 `agent get <target-aid> <key>` 的跨 Agent 读取对 owner/admin 开放,但普通 Agent 角色只获得安全摘要;敏感配置值和物理路径仅对 DaemonOwner 返回原值。跨 Agent 写入、启停、删除和 reload 仍遵循各自的目标与 DaemonOwner 权限边界。
|
|
100
|
-
- Agent 配置可包含 `fullaccess.enabled
|
|
100
|
+
- Agent 配置可包含 `fullaccess.enabled`(默认关闭)。可通过已认证的 EC Web Agent 设置修改;也可通过 Agent AID 的 `name: "agent"` Menu 管理自身,或通过 daemon Control AID 的同名 Menu 指定 `args.aid` 管理目标 Agent。Menu 写入要求请求者同时是目标 Agent Owner 与 daemon Owner;实际运行时也只有满足双 Owner 条件的直接私聊任务才会按调用使用宿主级 fullaccess。群聊、普通 Owner、跨 Agent 和 Trigger 不会因该开关自动提权。`/fa`、`/fullaccess` 和 Fullaccess Trigger 是内置能力,仍分别要求经过认证的 daemon Owner / 持久授权来源。
|
|
101
101
|
|
|
102
102
|
## 创建 Agent
|
|
103
103
|
|
|
@@ -58,7 +58,7 @@ ec config set configSnapshots false --process
|
|
|
58
58
|
|
|
59
59
|
```bash
|
|
60
60
|
# 立即创建快照(与当前版本比对,不一致才建;--full 强制新全量)(仅人)
|
|
61
|
-
ec config snapshot [--full] [--desc
|
|
61
|
+
ec config snapshot [--full] [--desc '<说明>']
|
|
62
62
|
|
|
63
63
|
# 列出快照版本(版本号/类型/触发/时间/说明)
|
|
64
64
|
ec config history
|
|
@@ -221,7 +221,7 @@ Menu 批量请求遇到真实权限拒绝仍整体拒绝并停止执行,不会
|
|
|
221
221
|
`role` 由角色分配服务维护;`permissionMode` 仅在角色策略中维护
|
|
222
222
|
- **兼容字段**:`enable_rich_content` 仍可读取旧值,但已废弃且不再产生运行时效果
|
|
223
223
|
- **群规则策略**:`groupRules.mode` 仅当前 Agent 的实际 owner 可 set/unset;DaemonOwner 不继承群或 relation 写权限,其他角色可读取当前 relation 的有效值
|
|
224
|
-
- **Agent fullaccess 策略**:Agent 配置中的 `fullaccess.enabled`
|
|
224
|
+
- **Agent fullaccess 策略**:Agent 配置中的 `fullaccess.enabled` 缺失时关闭。已认证的 EC Web Agent 设置可修改;Menu 可经 Agent AID 管理自身,或经 daemon Control AID 以 `args.aid` 指定目标 Agent,Menu 写入要求同一请求者同时是目标 Agent Owner 与 daemon Owner。CLI 和托管任务的 set/unset 均拒绝。双 Owner(Agent Owner + daemon Owner)条件在实际私聊任务执行时再次校验。`/fa`、`/fullaccess` 和 Fullaccess Trigger 不依赖此 Agent 级开关,而由各自的 daemon Owner 鉴权与批准链控制。
|
|
225
225
|
- **源码诊断白名单**:`readonlySourceDiagnostics` 默认关闭;开启后只读会话仅可在项目源码目录执行受限、可证明只读查询,配置/证书/快照/session/锁文件仍禁止访问
|
|
226
226
|
- **仅人可写**:channels / owners / admins / 凭证 / aid / enabled / projects / aun / models.allowed
|
|
227
227
|
- Agent 托管环境写仅人字段被拒
|
|
@@ -21,11 +21,11 @@ ec ctl name <新名称>
|
|
|
21
21
|
## 消息(兜底用)
|
|
22
22
|
|
|
23
23
|
```bash
|
|
24
|
-
ec ctl send
|
|
24
|
+
ec ctl send '<text>' # 主动发送文本(proactive 模式)
|
|
25
25
|
ec ctl file [channel] <path> # 发送项目内文件
|
|
26
26
|
```
|
|
27
27
|
|
|
28
|
-
> 发消息**首选 `ec msg send <self-aid> <peer-id>
|
|
28
|
+
> 发消息**首选 `ec msg send <self-aid> <peer-id> '<text>'`**(见 msg.md)。
|
|
29
29
|
> `ec ctl send` 只在拿不到自己的 AID 时兜底——它自动继承当前会话的 AID 和对端。
|
|
30
30
|
|
|
31
31
|
## 消息队列
|
|
@@ -281,7 +281,7 @@ metadata:
|
|
|
281
281
|
```bash
|
|
282
282
|
ec skill list [--json] # 列出所有技能:名称、来源、最终状态
|
|
283
283
|
ec skill info <name> [--json] # 单技能详情:路径、描述、三级开关、生效依据
|
|
284
|
-
ec skill create <name> [--desc
|
|
284
|
+
ec skill create <name> [--desc '...'] [--enable] # 新建技能骨架到本机级(默认禁用)
|
|
285
285
|
ec skill install <源> [--force] [--enable] # 安装技能(目录 / .zip / .md,默认禁用)
|
|
286
286
|
ec skill remove <name> # 删除本机技能(内置技能不能删)
|
|
287
287
|
ec skill enable <name> [--level agent|local]
|
|
@@ -534,9 +534,8 @@ ec fs cp a.agentid.pub:/x bob.agentid.pub:/refs/x # 跨主机
|
|
|
534
534
|
```bash
|
|
535
535
|
ec fs chmod +r <AID>:<path> # 公开可读
|
|
536
536
|
ec fs chmod o-r <AID>:<path> # 收回他人读权限
|
|
537
|
-
ec fs chmod <AID>:<path> --allow-roles admin #
|
|
537
|
+
ec fs chmod <AID>:<path> --allow-roles admin # 限定角色(多个角色用单引号包住逗号分隔)
|
|
538
538
|
ec fs chmod <AID>:<path> --visibility public|private
|
|
539
|
-
ec fs chmod <AID>:<path> --tags "a,b"
|
|
540
539
|
```
|
|
541
540
|
|
|
542
541
|
### 8.3 细粒度 AID 授权(setfacl)
|
|
@@ -1052,11 +1051,11 @@ alice.aid.pub:/projects/myapp/
|
|
|
1052
1051
|
### 17.5 命令集
|
|
1053
1052
|
|
|
1054
1053
|
```bash
|
|
1055
|
-
ec collab snapshot create <collab-root> [--major] [-m
|
|
1054
|
+
ec collab snapshot create <collab-root> [--major] [-m '<说明>'] # 创建快照(默认自动算 bump)
|
|
1056
1055
|
ec collab snapshot list <collab-root> # 列出所有快照
|
|
1057
1056
|
ec collab snapshot show <collab-root> <version> # 看某快照的完整 entries
|
|
1058
1057
|
ec collab snapshot diff <collab-root> <vA> <vB> # 比较两快照(doc 增删 / 版本变化)
|
|
1059
|
-
ec collab snapshot restore <collab-root> <version> [-m
|
|
1058
|
+
ec collab snapshot restore <collab-root> <version> [-m '<说明>'] # 回滚到某快照(非破坏性)
|
|
1060
1059
|
ec collab snapshot rm <collab-root> <version> # 删除指定快照(只删 manifest)
|
|
1061
1060
|
ec collab snapshot prune <collab-root> --before <date> [--keep-last <n>] # 按时间清理
|
|
1062
1061
|
```
|
|
@@ -1109,7 +1108,7 @@ forward 历史全部保留,任何时候都能再前滚。
|
|
|
1109
1108
|
```
|
|
1110
1109
|
✗ 快照创建失败:快照头已被他人推进(你基于 2.3.0,当前已是 2.4.0)
|
|
1111
1110
|
你的目录状态未受影响
|
|
1112
|
-
请重新执行: ec collab snapshot create alice.aid.pub:/projects/myapp -m
|
|
1111
|
+
请重新执行: ec collab snapshot create alice.aid.pub:/projects/myapp -m '...'
|
|
1113
1112
|
```
|
|
1114
1113
|
|
|
1115
1114
|
### 17.8 典型流程
|
package/kits/docs/evolcore/fs.md
CHANGED
|
@@ -53,7 +53,7 @@ ec fs umount <AID>:<path> # 卸载挂载点
|
|
|
53
53
|
- `--max-bytes <n>`:`cat` 最大直接输出字节数,默认 1MB
|
|
54
54
|
- `--head-bytes <n>`:`cat` 二进制头部字节数,默认 256
|
|
55
55
|
- `--visibility public|private`:`chmod` 可见性
|
|
56
|
-
- `--allow-roles <roles>`:`chmod`
|
|
56
|
+
- `--allow-roles <roles>`:`chmod` 角色约束,写法固定为单引号包住、逗号分隔,如 `--allow-roles 'owner,admin'`
|
|
57
57
|
- `-m aid:<aid>:<perms>` / `-x aid:<aid>`:`setfacl` 增删 ACL
|
|
58
58
|
- `--source <AID>:<path>` / `--volume <id>`:`mount` 来源
|
|
59
59
|
- `--expires <time>`:`mount/token/ACL` 过期时间,Unix 秒或 ISO 日期
|
|
@@ -151,8 +151,8 @@ ec group rules coordinator.agentid.pub <group-id> get --format json
|
|
|
151
151
|
|
|
152
152
|
```bash
|
|
153
153
|
ec group send coordinator.agentid.pub <group-id> \
|
|
154
|
-
|
|
155
|
-
--mention implementer.agentid.pub,reviewer.agentid.pub
|
|
154
|
+
'[A-001] API 重构协作启动。目标:完成 /collab/A-001/ 下的实现和回归报告。负责人:implementer;复核:reviewer;截止:2026-09-30 18:00。请先回复 ACK,再按规则汇报。' \
|
|
155
|
+
--mention 'implementer.agentid.pub,reviewer.agentid.pub'
|
|
156
156
|
```
|
|
157
157
|
|
|
158
158
|
每个任务至少包含:
|
|
@@ -14,10 +14,10 @@
|
|
|
14
14
|
|
|
15
15
|
```bash
|
|
16
16
|
# 文本(含空格/换行/特殊字符时用引号包起来;纯短词可不包,但多空格会被压成一个)
|
|
17
|
-
ec group send <from> <group-id>
|
|
17
|
+
ec group send <from> <group-id> '<text>' [--encrypt]
|
|
18
18
|
|
|
19
19
|
# 文件(--as image|video|voice|file)
|
|
20
|
-
ec group send <from> <group-id> --file <path> [--as <type>] [--text
|
|
20
|
+
ec group send <from> <group-id> --file <path> [--as <type>] [--text '<说明>']
|
|
21
21
|
|
|
22
22
|
# 自定义 payload
|
|
23
23
|
ec group send <from> <group-id> --payload '<json>'
|
|
@@ -33,12 +33,12 @@ ec group ack <from> <group-id> <seq> [--app <name>]
|
|
|
33
33
|
```
|
|
34
34
|
|
|
35
35
|
@ 成员:
|
|
36
|
-
- `--mention <
|
|
36
|
+
- `--mention '<aid1>,<aid2>'` — @ 某个成员。写法固定为单引号包住、逗号分隔,可多次传入,每个 aid 都过格式校验
|
|
37
37
|
- `--mention-all` — @ 所有人
|
|
38
38
|
|
|
39
39
|
```bash
|
|
40
|
-
ec group send <from> <group-id>
|
|
41
|
-
ec group send <from> <group-id>
|
|
40
|
+
ec group send <from> <group-id> '@bob 看下 PR' --mention 'bob.agentid.pub'
|
|
41
|
+
ec group send <from> <group-id> '通知' --mention 'alice.agentid.pub,bob.agentid.pub'
|
|
42
42
|
```
|
|
43
43
|
|
|
44
44
|
> 正文恰好以 `--` 开头:带空格的(如 `"--file 是正文"`)会被正确识别为正文;
|
|
@@ -88,7 +88,7 @@ owner/admin 按 Agent 管理范围查询其他群;visitor 默认拒绝。
|
|
|
88
88
|
|
|
89
89
|
```bash
|
|
90
90
|
# 创建群
|
|
91
|
-
ec group create <from>
|
|
91
|
+
ec group create <from> '<name>' [--visibility public|private] [--description '<desc>'] [--join-mode <mode>] [--group-id <aid>]
|
|
92
92
|
|
|
93
93
|
# 不指定 --group-id 时,默认名称为 g- 加五位随机数字(10000–99999)
|
|
94
94
|
# 例如返回 g-12345.agentid.cn;issuer 以群服务实际返回为准
|
|
@@ -104,7 +104,7 @@ ec group list <from> [--size <N>]
|
|
|
104
104
|
ec group info <from> <group-id>
|
|
105
105
|
|
|
106
106
|
# 修改群信息
|
|
107
|
-
ec group update <from> <group-id> [--name
|
|
107
|
+
ec group update <from> <group-id> [--name '<name>'] [--description '<desc>']
|
|
108
108
|
|
|
109
109
|
# 解散群
|
|
110
110
|
ec group dissolve <from> <group-id>
|
|
@@ -117,7 +117,7 @@ ec group resume <from> <group-id>
|
|
|
117
117
|
ec group rules <from> <group-id>
|
|
118
118
|
|
|
119
119
|
# 更新入群规则
|
|
120
|
-
ec group rules <from> <group-id> --mode open|approval|invite_only|closed [--question
|
|
120
|
+
ec group rules <from> <group-id> --mode open|approval|invite_only|closed [--question '<question>'] [--max-pending <N>]
|
|
121
121
|
|
|
122
122
|
# 查看已发布群规则文件 /rules.md
|
|
123
123
|
ec group rules <from> <group-id> get
|
|
@@ -178,7 +178,7 @@ admin、普通成员或仅具 daemon-owner 身份者不能代替该 Agent Owner
|
|
|
178
178
|
|
|
179
179
|
```bash
|
|
180
180
|
# 申请加入
|
|
181
|
-
ec group join <from> <group-id> [--message
|
|
181
|
+
ec group join <from> <group-id> [--message '<msg>'] [--answer '<answer>']
|
|
182
182
|
|
|
183
183
|
# 退出群
|
|
184
184
|
ec group leave <from> <group-id>
|
|
@@ -211,7 +211,7 @@ ec group ban <from> <group-id> <member-aid> [--duration <seconds>]
|
|
|
211
211
|
ec group unban <from> <group-id> <member-aid>
|
|
212
212
|
|
|
213
213
|
# 屏蔽成员接收群消息;member-aid 填 from 即屏蔽自己
|
|
214
|
-
ec group block <from> <group-id> <member-aid> [--reason
|
|
214
|
+
ec group block <from> <group-id> <member-aid> [--reason '<reason>']
|
|
215
215
|
|
|
216
216
|
# 取消屏蔽
|
|
217
217
|
ec group unblock <from> <group-id> <member-aid>
|
|
@@ -8,8 +8,8 @@
|
|
|
8
8
|
主会话写 note → pending/ → 整理会话产生正式记忆 → consolidated/ → 索引自动注入
|
|
9
9
|
```
|
|
10
10
|
|
|
11
|
-
- **note
|
|
12
|
-
- **正式记忆只由整理会话产生**:读 note 或候选记忆,判断取舍,用 `create` / `update` / `archive`
|
|
11
|
+
- **note 是原料**:主会话写,不分类、不判断层级,不进索引、不进台账。
|
|
12
|
+
- **正式记忆只由整理会话产生**:读 note 或候选记忆,判断取舍,用 `create` / `update` / `archive` 写入。程序负责登记完整性台账、重建索引、落日志。
|
|
13
13
|
|
|
14
14
|
## 三个作用域
|
|
15
15
|
|
|
@@ -68,10 +68,9 @@ $RELATIONS_DIR/<peerKey>/memory/ ← relation 作用域(note 唯一写入
|
|
|
68
68
|
├── pending/ # note 写入的临时记忆
|
|
69
69
|
│ └── archive/ # 被 drop 的 note
|
|
70
70
|
├── processing/ # 整理中的快照
|
|
71
|
-
├── consolidated/ #
|
|
71
|
+
├── consolidated/ # 正式记忆(已登记完整性台账)
|
|
72
72
|
└── archive/
|
|
73
|
-
|
|
74
|
-
└── invalid/ # 验签失败或未签名的文件
|
|
73
|
+
└── notes/ # 整理完成的 pending 原件
|
|
75
74
|
|
|
76
75
|
$PERSONAL_DIR/memory/ ← agent 作用域(结构相同,由泛化产出)
|
|
77
76
|
$EVOLCORE_HOME/memory/owner/<ownerAid>/ ← owner 作用域(结构相同,由提升产出)
|
|
@@ -23,7 +23,7 @@
|
|
|
23
23
|
│ │ ├─ 读上下文文件 │
|
|
24
24
|
│ │ ├─ 读候选记忆 │
|
|
25
25
|
│ │ ├─ create/update/archive
|
|
26
|
-
│ │ │ ├─
|
|
26
|
+
│ │ │ ├─ 登记
|
|
27
27
|
│ │ │ ├─ 日志落盘
|
|
28
28
|
│ │◄──── 会话结束 ───────────┤ │
|
|
29
29
|
│ onConsolidationComplete() │ │
|
|
@@ -63,24 +63,24 @@
|
|
|
63
63
|
|
|
64
64
|
## 三、三个写命令
|
|
65
65
|
|
|
66
|
-
整理会话只能用这三个命令写正式记忆。**不允许用 Write / Edit
|
|
66
|
+
整理会话只能用这三个命令写正式记忆。**不允许用 Write / Edit 直接写文件**——那会绕过完整性台账和索引,被当作带外修改恢复掉。
|
|
67
67
|
|
|
68
68
|
### create — 新建
|
|
69
69
|
|
|
70
70
|
```bash
|
|
71
|
-
ec memory create --scope <relation|agent|owner> --slug <slug> --desc
|
|
72
|
-
--tags <tag1
|
|
71
|
+
ec memory create --scope <relation|agent|owner> --slug <slug> --desc '一句话描述' \
|
|
72
|
+
--tags '<tag1>,<tag2>' [--keywords '<kw1>,<kw2>'] [--replaces '<路径1>,<路径2>'] '<正文>'
|
|
73
73
|
```
|
|
74
74
|
|
|
75
|
-
-
|
|
75
|
+
- 程序负责写入 `consolidated/`、登记完整性台账、重建索引。
|
|
76
76
|
- `--replaces` 指定的旧文件会被自动归档——**合并、纠正内容、升格作用域都走这条路径**,一次调用完成,不会出现「新的写了、旧的没归档」的重复记忆。
|
|
77
77
|
- **目标 slug 已存在且未在 `--replaces` 里列出 → 拒绝**,报错回传已有文件路径。这是防止漏用 `--replaces` 导致静默覆盖的闸门。
|
|
78
|
-
- **正文上限 10KB**,超出报 `MEMORY_TOO_LARGE
|
|
78
|
+
- **正文上限 10KB**,超出报 `MEMORY_TOO_LARGE`。这不是技术限制,而是记忆的性质决定的:一条记忆应当是**一句话能说清的结论**。内容确实那么多时,拆成多条分别 `create`,或把细节留在归档文件里、记忆只记结论。
|
|
79
79
|
|
|
80
80
|
### update — 只改标签
|
|
81
81
|
|
|
82
82
|
```bash
|
|
83
|
-
ec memory update <路径> --tags <tag1
|
|
83
|
+
ec memory update <路径> --tags '<tag1>,<tag2>' # 整体替换标签
|
|
84
84
|
ec memory update <路径> --touch # 刷新 mtime 与 updatedAt,用于续期
|
|
85
85
|
```
|
|
86
86
|
|
|
@@ -175,12 +175,17 @@ daemon 按整理会话的模式校验 `--scope`:
|
|
|
175
175
|
|
|
176
176
|
**能**:
|
|
177
177
|
|
|
178
|
-
- 用 Read / Glob / Grep
|
|
178
|
+
- 用 Read / Glob / Grep 读任务书、`processing/`、`consolidated/`、`MEMORY.md`、本对话流水。
|
|
179
179
|
- 用 Bash 执行**单条** `ec memory create` / `update` / `archive` 写正式记忆。
|
|
180
|
+
- 用 Write / Edit 写任务书里指定的**反馈文件**(`<batchDir>/scratch/feedback.txt`)。
|
|
181
|
+
这是本会话唯一可写的文件:其余任何路径(含同目录下的其他文件)都拒绝。
|
|
182
|
+
未写入则收尾时回退到默认统计模板(模式、触发方式、耗时、新建/更新/归档条数等)。
|
|
183
|
+
`scratch/` 是会话期临时工作区:收尾时读出反馈写入 `batch.md` 的 `feedbackText`,随后整个目录删除(不分成败)。
|
|
180
184
|
|
|
181
185
|
**不能**(程序拦截,提示「整理会话不允许执行此命令」):
|
|
182
186
|
|
|
183
|
-
- Write / Edit / MultiEdit / NotebookEdit(Codex
|
|
187
|
+
- Write / Edit / MultiEdit / NotebookEdit(Codex 的文件变更同理)写反馈文件以外的任何路径——直接写文件绕过完整性台账和索引。
|
|
188
|
+
- 经由 shell 写文件(`apply_patch`、重定向、`tee` 等):同一个入参在不同 runner 里的含义不同,无法证明它写的就是那个文件。
|
|
184
189
|
- 子代理(Agent / Task)、PowerShell——能绕开本策略。
|
|
185
190
|
- Bash 里的其他任何命令,包括 `ls`、`cat`、`npm`、`git`,以及 `ec memory note` / `ec memory consolidate`
|
|
186
191
|
(note 是主会话入口,用了会把结果变回原料;consolidate 会形成循环)。
|
|
@@ -194,7 +199,7 @@ daemon 按整理会话的模式校验 `--scope`:
|
|
|
194
199
|
|
|
195
200
|
- 逐一读取所有 consolidated 文件查重。先查 `MEMORY.md` 索引,只在发现高度相似的描述时才读那一条确认。
|
|
196
201
|
|
|
197
|
-
实现:`src/core/
|
|
202
|
+
实现:`src/core/system-session/memory.ts`,由 response-engine 在 `sessionType=memory` 的会话上挂为最终判定(`systemSessionCheck`);同一份声明(`grants()`:可读根 + 唯一可写文件)同时交给 runner 的沙箱 / 工具执行器,Claude / Codex / ecagent 三个 runner 共用,与角色体系无关。整理 trigger 不带 `permissionMode`,不会进入 fullaccess,策略不会被跳过。
|
|
198
203
|
|
|
199
204
|
---
|
|
200
205
|
|
|
@@ -206,13 +211,12 @@ daemon 按整理会话的模式校验 `--scope`:
|
|
|
206
211
|
├── pending/ # note 写入;整理前整体移到 processing/
|
|
207
212
|
│ └── archive/ # 被 drop 的 note
|
|
208
213
|
├── processing/ # 整理中快照
|
|
209
|
-
├── consolidated/ #
|
|
214
|
+
├── consolidated/ # 正式记忆(已登记完整性台账),文件名即 <slug>.md
|
|
210
215
|
└── archive/
|
|
211
|
-
|
|
212
|
-
└── invalid/ # 验签失败或未签名的文件
|
|
216
|
+
└── notes/ # 整理完成的 pending 原件
|
|
213
217
|
```
|
|
214
218
|
|
|
215
|
-
**索引**:每个作用域一份,上限 `memory.indexMaxBytes`(默认 5KB
|
|
219
|
+
**索引**:每个作用域一份,上限 `memory.indexMaxBytes`(默认 5KB)。重建时**逐份过完整性台账**:被带外修改的先恢复到最后登记的版本再进索引,被改动且无法恢复的跳过、不移动文件。筛选顺序:
|
|
216
220
|
|
|
217
221
|
1. `important`、`urgent`、`profile` 必进,**永不淘汰**
|
|
218
222
|
2. `in-progress`、`pending`、`blocked`
|
|
@@ -53,7 +53,9 @@ tags: [important, long-term, rule, verified]
|
|
|
53
53
|
- 打上 `to-generalize` → 下次泛化模式会扫到它,评估能否升到 agent 级。
|
|
54
54
|
- 打上 `to-promote` → 下次提升模式会扫到它,评估能否升到 owner 级。
|
|
55
55
|
|
|
56
|
-
|
|
56
|
+
**打标的地方**:整理会话写正式记忆(`ec memory create --tags 'a,b'`,事后用 `ec memory update --tags 'a,b'` 整体替换),主会话写 note(`ec memory note --tags 'a,b'`)。note 的标签是临时的,整理会话读取后决定去留。
|
|
57
|
+
|
|
58
|
+
写法固定为单引号包住、逗号分隔:`--tags 'to-generalize,urgent'`。
|
|
57
59
|
|
|
58
60
|
**清标的两种方式**:
|
|
59
61
|
|