metame-cli 1.6.2 → 1.6.4
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/README.md +12 -2
- package/index.js +86 -6
- package/package.json +1 -1
- package/scripts/agent-intent-shared.js +11 -2
- package/scripts/core/session-source-db.js +125 -0
- package/scripts/daemon-agent-intent.js +51 -15
- package/scripts/daemon-agent-tools.js +52 -3
- package/scripts/daemon-agent-workflow.js +98 -0
- package/scripts/daemon-bridges.js +9 -2
- package/scripts/daemon-claude-engine.js +12 -3
- package/scripts/daemon-command-router.js +9 -20
- package/scripts/daemon-engine-runtime.js +16 -6
- package/scripts/daemon-runtime-lifecycle.js +23 -0
- package/scripts/daemon-user-acl.js +19 -1
- package/scripts/daemon-weixin-bridge.js +6 -2
- package/scripts/daemon.js +50 -4
- package/scripts/docs/hermes-memory-upgrade-converged.md +461 -0
- package/scripts/docs/hermes-memory-upgrade-plan.md +506 -0
- package/scripts/feishu-adapter.js +78 -2
- package/scripts/memory-extract.js +72 -4
- package/scripts/memory-wiki-schema.js +31 -0
- package/scripts/memory.js +8 -2
- package/skills/agent-management/SKILL.md +101 -0
- package/skills/send-to-user/SKILL.md +76 -0
|
@@ -0,0 +1,461 @@
|
|
|
1
|
+
# MetaMe Hermes-Style Memory Upgrade: Converged Landing Plan
|
|
2
|
+
|
|
3
|
+
Status: converged proposal for implementation review
|
|
4
|
+
Principle: extend the existing memory pipeline; do not replace it
|
|
5
|
+
|
|
6
|
+
## 0. Final Architecture Decision
|
|
7
|
+
|
|
8
|
+
Do not build a parallel Hermes clone.
|
|
9
|
+
|
|
10
|
+
MetaMe already has the right primitives:
|
|
11
|
+
|
|
12
|
+
- `memory_items` in `scripts/memory.js` for facts, conventions, profiles, and episodes.
|
|
13
|
+
- FTS5 over `memory_items`.
|
|
14
|
+
- `wiki_pages`, `content_chunks`, and `embedding_queue` from `scripts/memory-wiki-schema.js`.
|
|
15
|
+
- Hybrid wiki retrieval in `scripts/core/hybrid-search.js`.
|
|
16
|
+
- Session skeleton/evidence extraction in `scripts/session-analytics.js`.
|
|
17
|
+
- Atomic fact extraction in `scripts/memory-extract.js`.
|
|
18
|
+
- Per-agent memory snapshot injection in `scripts/agent-layer.js`.
|
|
19
|
+
|
|
20
|
+
The elegant landing is therefore:
|
|
21
|
+
|
|
22
|
+
```
|
|
23
|
+
raw transcript provenance table
|
|
24
|
+
+ existing memory_items(kind='episode') as session note
|
|
25
|
+
+ existing memory_items(kind='convention'|'insight') as extracted facts
|
|
26
|
+
+ existing wiki_pages as compiled knowledge
|
|
27
|
+
+ new recall-router for on-demand prompt injection
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Only one new durable table is required in the first landing: `session_sources`.
|
|
31
|
+
|
|
32
|
+
## 1. Why This Is the Converged Version
|
|
33
|
+
|
|
34
|
+
The previous RFC suggested both `session_episodes` and `session_notes`. After reviewing current source, that is heavier than necessary:
|
|
35
|
+
|
|
36
|
+
- `memory_items.kind='episode'` already represents session summaries and is consumed by `searchSessions()` and wiki export.
|
|
37
|
+
- `wiki-reflect-export.js` already exports session summaries into `wiki/sessions/`.
|
|
38
|
+
- `memory-extract.js` already calls `memory.saveSession()` after processing Claude and Codex sessions.
|
|
39
|
+
- Adding a separate `session_notes` table would duplicate existing `episode` rows and force new export/search paths.
|
|
40
|
+
|
|
41
|
+
So the minimum stable design is:
|
|
42
|
+
|
|
43
|
+
- Add `session_sources` for L0 provenance.
|
|
44
|
+
- Upgrade `saveSession()` content quality and metadata.
|
|
45
|
+
- Add query-time recall routing.
|
|
46
|
+
- Keep all existing public memory APIs backward compatible.
|
|
47
|
+
|
|
48
|
+
## 2. Target Data Model
|
|
49
|
+
|
|
50
|
+
### 2.1 New Table: `session_sources`
|
|
51
|
+
|
|
52
|
+
Add in `scripts/memory-wiki-schema.js` or a new schema helper called by `memory.js`.
|
|
53
|
+
|
|
54
|
+
Purpose: immutable-ish provenance index for raw session material.
|
|
55
|
+
|
|
56
|
+
```sql
|
|
57
|
+
CREATE TABLE IF NOT EXISTS session_sources (
|
|
58
|
+
id TEXT PRIMARY KEY,
|
|
59
|
+
engine TEXT NOT NULL DEFAULT 'unknown',
|
|
60
|
+
session_id TEXT NOT NULL,
|
|
61
|
+
project TEXT DEFAULT '*',
|
|
62
|
+
scope TEXT,
|
|
63
|
+
agent_key TEXT,
|
|
64
|
+
cwd TEXT,
|
|
65
|
+
source_path TEXT,
|
|
66
|
+
source_hash TEXT,
|
|
67
|
+
source_size INTEGER DEFAULT 0,
|
|
68
|
+
first_ts TEXT,
|
|
69
|
+
last_ts TEXT,
|
|
70
|
+
message_count INTEGER DEFAULT 0,
|
|
71
|
+
tool_call_count INTEGER DEFAULT 0,
|
|
72
|
+
tool_error_count INTEGER DEFAULT 0,
|
|
73
|
+
status TEXT DEFAULT 'indexed'
|
|
74
|
+
CHECK (status IN ('indexed','summarized','extracted','error','archived')),
|
|
75
|
+
error_message TEXT,
|
|
76
|
+
created_at TEXT DEFAULT (datetime('now')),
|
|
77
|
+
updated_at TEXT DEFAULT (datetime('now')),
|
|
78
|
+
UNIQUE(engine, session_id, source_hash)
|
|
79
|
+
);
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Indexes:
|
|
83
|
+
|
|
84
|
+
```sql
|
|
85
|
+
CREATE INDEX IF NOT EXISTS idx_session_sources_session ON session_sources(session_id);
|
|
86
|
+
CREATE INDEX IF NOT EXISTS idx_session_sources_project ON session_sources(project, scope, last_ts);
|
|
87
|
+
CREATE INDEX IF NOT EXISTS idx_session_sources_agent ON session_sources(agent_key, last_ts);
|
|
88
|
+
```
|
|
89
|
+
|
|
90
|
+
### 2.2 Reuse Existing Table: `memory_items`
|
|
91
|
+
|
|
92
|
+
Do not add `session_notes` table.
|
|
93
|
+
|
|
94
|
+
Use:
|
|
95
|
+
|
|
96
|
+
- `kind='episode'` for L1 session note.
|
|
97
|
+
- `source_type='session' | 'codex'`.
|
|
98
|
+
- `source_id=session_id`.
|
|
99
|
+
- `session_id=session_id`.
|
|
100
|
+
- `project`, `scope`, and `agent_key` as routing metadata.
|
|
101
|
+
|
|
102
|
+
Add only these columns if reviewers agree they are worth it:
|
|
103
|
+
|
|
104
|
+
```sql
|
|
105
|
+
ALTER TABLE memory_items ADD COLUMN source_hash TEXT;
|
|
106
|
+
ALTER TABLE memory_items ADD COLUMN review_state TEXT DEFAULT 'unreviewed';
|
|
107
|
+
ALTER TABLE memory_items ADD COLUMN valid_from TEXT;
|
|
108
|
+
ALTER TABLE memory_items ADD COLUMN valid_to TEXT;
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
Strict minimum: `source_hash` is enough for phase 1.
|
|
112
|
+
|
|
113
|
+
## 3. Implementation Sequence
|
|
114
|
+
|
|
115
|
+
### PR 1: Provenance Index Only
|
|
116
|
+
|
|
117
|
+
Goal: make every processed Claude/Codex transcript traceable without changing behavior.
|
|
118
|
+
|
|
119
|
+
Files:
|
|
120
|
+
|
|
121
|
+
- Add `scripts/core/session-source-db.js`
|
|
122
|
+
- Update `scripts/memory-wiki-schema.js`
|
|
123
|
+
- Update `scripts/memory.js` DB init if schema is split
|
|
124
|
+
- Add `scripts/core/session-source-db.test.js`
|
|
125
|
+
|
|
126
|
+
`session-source-db.js` API:
|
|
127
|
+
|
|
128
|
+
```js
|
|
129
|
+
function upsertSessionSource(db, source) {}
|
|
130
|
+
function getSessionSource(db, { engine, sessionId, sourceHash }) {}
|
|
131
|
+
function findSessionSources(db, { project, scope, engine, limit }) {}
|
|
132
|
+
function markSessionSourceStatus(db, id, status, errorMessage) {}
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
Rules:
|
|
136
|
+
|
|
137
|
+
- The module is pure DB logic.
|
|
138
|
+
- It does not read transcript files.
|
|
139
|
+
- It does not call LLMs.
|
|
140
|
+
- It does not know daemon state.
|
|
141
|
+
|
|
142
|
+
Integration:
|
|
143
|
+
|
|
144
|
+
- In `memory-extract.js`, after `extractSkeleton()` or `buildCodexInput()`, compute `source_hash` from the source file.
|
|
145
|
+
- Upsert `session_sources`.
|
|
146
|
+
- Continue existing fact/session extraction unchanged.
|
|
147
|
+
|
|
148
|
+
Acceptance:
|
|
149
|
+
|
|
150
|
+
- Re-running `memory-extract.js` on the same transcript does not duplicate rows.
|
|
151
|
+
- Existing tests for `memory-extract` and wiki still pass.
|
|
152
|
+
- `memory.searchSessions()` output is unchanged.
|
|
153
|
+
|
|
154
|
+
### PR 2: Better Episode Notes, Same Storage
|
|
155
|
+
|
|
156
|
+
Goal: make `memory_items.kind='episode'` useful as a session wiki source even when no atomic facts are extracted.
|
|
157
|
+
|
|
158
|
+
Files:
|
|
159
|
+
|
|
160
|
+
- Add `scripts/core/session-note.js`
|
|
161
|
+
- Update `scripts/memory-extract.js`
|
|
162
|
+
- Extend `scripts/memory.js saveSession()`
|
|
163
|
+
- Add `scripts/core/session-note.test.js`
|
|
164
|
+
|
|
165
|
+
`session-note.js` should be pure:
|
|
166
|
+
|
|
167
|
+
```js
|
|
168
|
+
function buildSessionNote({ skeleton, evidence, sessionName, facts }) {
|
|
169
|
+
return {
|
|
170
|
+
title,
|
|
171
|
+
summary,
|
|
172
|
+
keywords,
|
|
173
|
+
content,
|
|
174
|
+
};
|
|
175
|
+
}
|
|
176
|
+
```
|
|
177
|
+
|
|
178
|
+
Recommended content format:
|
|
179
|
+
|
|
180
|
+
```markdown
|
|
181
|
+
## Task
|
|
182
|
+
<from user snippets / inferred intent>
|
|
183
|
+
|
|
184
|
+
## Outcome
|
|
185
|
+
<facts or concise execution result>
|
|
186
|
+
|
|
187
|
+
## Evidence
|
|
188
|
+
- session_id: ...
|
|
189
|
+
- project: ...
|
|
190
|
+
- duration: ...
|
|
191
|
+
- tools: ...
|
|
192
|
+
- errors: ...
|
|
193
|
+
```
|
|
194
|
+
|
|
195
|
+
Use this content as the `summary` passed to `saveSession()`. Keep the API name for compatibility even if the content becomes richer than a one-line summary.
|
|
196
|
+
|
|
197
|
+
Acceptance:
|
|
198
|
+
|
|
199
|
+
- Sessions with zero extracted facts still produce a useful episode row.
|
|
200
|
+
- `memory-search.js --sessions "<query>"` can find session notes by task words, file paths, and error terms.
|
|
201
|
+
- `wiki-reflect-export.js` continues to export session summaries without a new path.
|
|
202
|
+
|
|
203
|
+
### PR 3: Scope Resolver
|
|
204
|
+
|
|
205
|
+
Goal: stop scattering project/scope/agent inference.
|
|
206
|
+
|
|
207
|
+
Files:
|
|
208
|
+
|
|
209
|
+
- Add `scripts/core/memory-scope.js`
|
|
210
|
+
- Use it in `memory-extract.js`, `agent-layer.js`, later `daemon-claude-engine.js`
|
|
211
|
+
- Add `scripts/core/memory-scope.test.js`
|
|
212
|
+
|
|
213
|
+
API:
|
|
214
|
+
|
|
215
|
+
```js
|
|
216
|
+
function normalizeMemoryScope(input) {
|
|
217
|
+
return {
|
|
218
|
+
project,
|
|
219
|
+
scope,
|
|
220
|
+
agentKey,
|
|
221
|
+
sessionId,
|
|
222
|
+
engine,
|
|
223
|
+
cwd,
|
|
224
|
+
};
|
|
225
|
+
}
|
|
226
|
+
```
|
|
227
|
+
|
|
228
|
+
Rules:
|
|
229
|
+
|
|
230
|
+
- It is pure.
|
|
231
|
+
- It accepts partial inputs.
|
|
232
|
+
- It never reads `daemon.yaml`.
|
|
233
|
+
- Callers that need daemon config resolve project before calling this helper.
|
|
234
|
+
|
|
235
|
+
Acceptance:
|
|
236
|
+
|
|
237
|
+
- Claude and Codex extraction produce consistent `project/scope/engine`.
|
|
238
|
+
- Existing `project_id` behavior remains compatible.
|
|
239
|
+
|
|
240
|
+
### PR 4: Recall Router in Observe-Only Mode
|
|
241
|
+
|
|
242
|
+
Goal: decide when historical memory should be retrieved, but do not inject yet.
|
|
243
|
+
|
|
244
|
+
Files:
|
|
245
|
+
|
|
246
|
+
- Add `scripts/core/recall-router.js`
|
|
247
|
+
- Add `scripts/core/recall-router.test.js`
|
|
248
|
+
- Optionally log decisions from `daemon-claude-engine.js` without changing prompt
|
|
249
|
+
|
|
250
|
+
API:
|
|
251
|
+
|
|
252
|
+
```js
|
|
253
|
+
function planRecall({ text, scope, hasActiveSession }) {
|
|
254
|
+
return {
|
|
255
|
+
shouldRecall,
|
|
256
|
+
reason,
|
|
257
|
+
queries,
|
|
258
|
+
modes,
|
|
259
|
+
maxChars,
|
|
260
|
+
};
|
|
261
|
+
}
|
|
262
|
+
```
|
|
263
|
+
|
|
264
|
+
Initial trigger rules:
|
|
265
|
+
|
|
266
|
+
- history words: `之前`, `上次`, `以前`, `记得`, `回忆`, `查历史`, `有没有踩过坑`
|
|
267
|
+
- decision words: `为什么这么定`, `当时怎么决定`, `以前怎么处理`
|
|
268
|
+
- bug recurrence: `又`, `再次`, `之前的 bug`, `同样的问题`
|
|
269
|
+
- exact identifiers: file path, function name, config key, error code
|
|
270
|
+
|
|
271
|
+
Initial non-triggers:
|
|
272
|
+
|
|
273
|
+
- pure commands: `/status`, `/tasks`, `/agent`
|
|
274
|
+
- obvious one-shot shell/math/date requests
|
|
275
|
+
- messages shorter than 4 chars unless they are explicit history commands
|
|
276
|
+
|
|
277
|
+
Acceptance:
|
|
278
|
+
|
|
279
|
+
- Router is deterministic.
|
|
280
|
+
- Unit tests cover Chinese triggers.
|
|
281
|
+
- No prompt behavior changes in this PR.
|
|
282
|
+
|
|
283
|
+
### PR 5: Recall Assembly API
|
|
284
|
+
|
|
285
|
+
Goal: centralize query-conditioned recall.
|
|
286
|
+
|
|
287
|
+
Files:
|
|
288
|
+
|
|
289
|
+
- Extend `scripts/memory.js`
|
|
290
|
+
- Possibly add `scripts/core/recall-format.js`
|
|
291
|
+
- Add tests in `scripts/memory-wiki-integration.test.js` or new `scripts/memory-recall.test.js`
|
|
292
|
+
|
|
293
|
+
API:
|
|
294
|
+
|
|
295
|
+
```js
|
|
296
|
+
async function assembleRecallContext({
|
|
297
|
+
query,
|
|
298
|
+
scope,
|
|
299
|
+
modes = ['facts', 'sessions', 'wiki'],
|
|
300
|
+
maxChars = 4000,
|
|
301
|
+
ftsOnly = false,
|
|
302
|
+
}) {}
|
|
303
|
+
```
|
|
304
|
+
|
|
305
|
+
Output:
|
|
306
|
+
|
|
307
|
+
```js
|
|
308
|
+
{
|
|
309
|
+
text: "...bounded markdown block...",
|
|
310
|
+
sources: [
|
|
311
|
+
{ type: 'fact', id: '...' },
|
|
312
|
+
{ type: 'session', session_id: '...' },
|
|
313
|
+
{ type: 'wiki', slug: '...' }
|
|
314
|
+
],
|
|
315
|
+
truncated: false
|
|
316
|
+
}
|
|
317
|
+
```
|
|
318
|
+
|
|
319
|
+
Rules:
|
|
320
|
+
|
|
321
|
+
- Facts: active facts only by default.
|
|
322
|
+
- Sessions: use `searchSessions()`.
|
|
323
|
+
- Wiki: use existing `hybridSearchWiki()`.
|
|
324
|
+
- Include provenance labels.
|
|
325
|
+
- Never include raw transcripts.
|
|
326
|
+
- Hard cap by characters.
|
|
327
|
+
|
|
328
|
+
Acceptance:
|
|
329
|
+
|
|
330
|
+
- Empty search returns empty text.
|
|
331
|
+
- Relevance is stable under missing embeddings.
|
|
332
|
+
- Works with FTS-only fallback.
|
|
333
|
+
|
|
334
|
+
### PR 6: Prompt Injection Behind Feature Flag
|
|
335
|
+
|
|
336
|
+
Goal: add Hermes-style on-demand memory without destabilizing normal chats.
|
|
337
|
+
|
|
338
|
+
Files:
|
|
339
|
+
|
|
340
|
+
- `scripts/daemon-claude-engine.js`
|
|
341
|
+
- `scripts/daemon-prompt-context.js`
|
|
342
|
+
- `scripts/daemon-prompt-context.test.js`
|
|
343
|
+
- Maybe `scripts/daemon-claude-engine.test.js`
|
|
344
|
+
|
|
345
|
+
Behavior:
|
|
346
|
+
|
|
347
|
+
- Existing `memory-snapshot.md` injection remains unchanged.
|
|
348
|
+
- Before composing the final prompt, call `planRecall()`.
|
|
349
|
+
- If enabled and `shouldRecall`, call `memory.assembleRecallContext()`.
|
|
350
|
+
- Inject as:
|
|
351
|
+
|
|
352
|
+
```text
|
|
353
|
+
[Relevant memory recall:
|
|
354
|
+
...
|
|
355
|
+
]
|
|
356
|
+
```
|
|
357
|
+
|
|
358
|
+
Feature flag:
|
|
359
|
+
|
|
360
|
+
Do not require config in PR 1-5.
|
|
361
|
+
|
|
362
|
+
For PR 6, read optional runtime config from `~/.metame/daemon.yaml`:
|
|
363
|
+
|
|
364
|
+
```yaml
|
|
365
|
+
daemon:
|
|
366
|
+
memory_recall_enabled: false
|
|
367
|
+
memory_recall_max_chars: 4000
|
|
368
|
+
```
|
|
369
|
+
|
|
370
|
+
Template changes in `scripts/daemon-default.yaml` are optional and must contain placeholders only.
|
|
371
|
+
|
|
372
|
+
Acceptance:
|
|
373
|
+
|
|
374
|
+
- Default behavior is unchanged because flag is false.
|
|
375
|
+
- With flag true, recall block appears only for router-triggered messages.
|
|
376
|
+
- No daemon prompt exceeds configured recall cap.
|
|
377
|
+
- If DB/search fails, prompt proceeds without recall.
|
|
378
|
+
|
|
379
|
+
## 4. What Not To Do
|
|
380
|
+
|
|
381
|
+
Do not:
|
|
382
|
+
|
|
383
|
+
- Create a second memory DB.
|
|
384
|
+
- Create `session_notes` table in the first landing.
|
|
385
|
+
- Copy full transcripts into `memory.db`.
|
|
386
|
+
- Inject recent sessions into every prompt.
|
|
387
|
+
- Let subagents write verified/global memory directly.
|
|
388
|
+
- Change `plugin/scripts/` or deployed `~/.metame/` files directly.
|
|
389
|
+
- Edit real user config in `~/.metame/daemon.yaml` as part of source changes.
|
|
390
|
+
|
|
391
|
+
## 5. Review-Critical Invariants
|
|
392
|
+
|
|
393
|
+
Experts should hold the implementation to these invariants:
|
|
394
|
+
|
|
395
|
+
1. L0 provenance is immutable enough.
|
|
396
|
+
A raw transcript pointer + hash must survive all derived memory changes.
|
|
397
|
+
|
|
398
|
+
2. Derived memory is rebuildable.
|
|
399
|
+
Episode notes and facts can be regenerated from source material.
|
|
400
|
+
|
|
401
|
+
3. Recall is query-conditioned.
|
|
402
|
+
No broad "always inject history" behavior.
|
|
403
|
+
|
|
404
|
+
4. Prompt cache is mostly preserved.
|
|
405
|
+
Normal messages should not receive dynamic recall blocks.
|
|
406
|
+
|
|
407
|
+
5. Existing APIs stay compatible.
|
|
408
|
+
`saveFacts`, `saveSession`, `searchFacts`, `searchSessions`, `recentSessions`, and `hybridSearchWiki` keep working.
|
|
409
|
+
|
|
410
|
+
6. Scope is explicit.
|
|
411
|
+
Project/agent/thread memory does not bleed into unrelated sessions.
|
|
412
|
+
|
|
413
|
+
7. Failure is soft.
|
|
414
|
+
Memory extraction/search failures never block the user-facing task.
|
|
415
|
+
|
|
416
|
+
## 6. Minimal Test Plan
|
|
417
|
+
|
|
418
|
+
Run after PR 1-3:
|
|
419
|
+
|
|
420
|
+
```bash
|
|
421
|
+
node --test scripts/core/session-source-db.test.js
|
|
422
|
+
node --test scripts/core/session-note.test.js
|
|
423
|
+
node --test scripts/memory-wiki-integration.test.js
|
|
424
|
+
node --test scripts/memory-extract-step4.test.js
|
|
425
|
+
```
|
|
426
|
+
|
|
427
|
+
Run after PR 4-5:
|
|
428
|
+
|
|
429
|
+
```bash
|
|
430
|
+
node --test scripts/core/recall-router.test.js
|
|
431
|
+
node --test scripts/memory-wiki-integration.test.js
|
|
432
|
+
node --test scripts/wiki-reflect-export.test.js
|
|
433
|
+
```
|
|
434
|
+
|
|
435
|
+
Run after PR 6:
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
npx eslint scripts/daemon*.js
|
|
439
|
+
node --test scripts/daemon-prompt-context.test.js
|
|
440
|
+
node --test scripts/daemon-claude-engine.test.js
|
|
441
|
+
node --test scripts/daemon-*.test.js
|
|
442
|
+
```
|
|
443
|
+
|
|
444
|
+
## 7. First Implementation Patch Shape
|
|
445
|
+
|
|
446
|
+
The first implementation patch should be this small:
|
|
447
|
+
|
|
448
|
+
1. Add `session_sources` DDL.
|
|
449
|
+
2. Add `scripts/core/session-source-db.js`.
|
|
450
|
+
3. Add `scripts/core/session-source-db.test.js`.
|
|
451
|
+
4. Call `upsertSessionSource()` from `memory-extract.js` for Claude and Codex paths.
|
|
452
|
+
5. Do not add prompt recall.
|
|
453
|
+
6. Do not add config.
|
|
454
|
+
7. Do not alter wiki export behavior.
|
|
455
|
+
|
|
456
|
+
Expected review outcome:
|
|
457
|
+
|
|
458
|
+
- Easy to verify.
|
|
459
|
+
- Easy to roll back.
|
|
460
|
+
- Gives future PRs a provenance anchor.
|
|
461
|
+
|