@zenera/cli 1.1.25 → 1.1.27
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 +13 -1
- package/dist/catalog.d.ts +20 -0
- package/dist/catalog.js +60 -0
- package/dist/commands/index.js +2 -0
- package/dist/commands/inspect.d.ts +5 -1
- package/dist/commands/inspect.js +54 -14
- package/dist/commands/memory.js +28 -3
- package/dist/commands/meta.js +24 -5
- package/dist/commands/models.js +2 -1
- package/dist/commands/sandbox.js +73 -3
- package/dist/commands/view.d.ts +8 -0
- package/dist/commands/view.js +114 -0
- package/dist/engine.d.ts +3 -1
- package/dist/engine.js +6 -0
- package/dist/eventlog.d.ts +5 -0
- package/dist/eventlog.js +25 -1
- package/dist/liveness.js +20 -2
- package/dist/main.js +0 -0
- package/dist/meta/editor.d.ts +1 -1
- package/dist/meta/editor.js +4 -21
- package/dist/meta/finetune/analyze-brief.d.ts +26 -0
- package/dist/meta/finetune/analyze-brief.js +131 -0
- package/dist/meta/finetune/apply-brief.d.ts +23 -0
- package/dist/meta/finetune/apply-brief.js +247 -0
- package/dist/meta/finetune/brief.d.ts +45 -0
- package/dist/meta/finetune/brief.js +158 -0
- package/dist/meta/finetune/command.d.ts +1 -1
- package/dist/meta/finetune/command.js +224 -46
- package/dist/meta/finetune/cost.d.ts +46 -0
- package/dist/meta/finetune/cost.js +105 -0
- package/dist/meta/finetune/dataset/types.d.ts +3 -1
- package/dist/meta/finetune/feedback.d.ts +14 -2
- package/dist/meta/finetune/feedback.js +22 -3
- package/dist/meta/finetune/guard.d.ts +29 -0
- package/dist/meta/finetune/guard.js +104 -0
- package/dist/meta/finetune/improvements.d.ts +50 -3
- package/dist/meta/finetune/improvements.js +290 -33
- package/dist/meta/finetune/live.d.ts +17 -7
- package/dist/meta/finetune/live.js +56 -10
- package/dist/meta/finetune/loop.js +59 -10
- package/dist/meta/finetune/recheck.d.ts +58 -0
- package/dist/meta/finetune/recheck.js +311 -0
- package/dist/meta/finetune/report.d.ts +9 -2
- package/dist/meta/finetune/report.js +551 -438
- package/dist/meta/finetune/sampler.js +8 -2
- package/dist/meta/finetune/train.d.ts +6 -2
- package/dist/meta/finetune/train.js +55 -21
- package/dist/meta/finetune/tui.d.ts +3 -3
- package/dist/meta/finetune/tui.js +37 -12
- package/dist/meta/finetune/tuning.d.ts +27 -1
- package/dist/meta/finetune/tuning.js +21 -2
- package/dist/meta/finetune/usage.d.ts +4 -0
- package/dist/meta/finetune/usage.js +35 -0
- package/dist/meta/finetune/view.d.ts +9 -0
- package/dist/meta/finetune/view.js +27 -0
- package/dist/meta/host.d.ts +2 -1
- package/dist/meta/host.js +2 -1
- package/dist/meta.d.ts +291 -0
- package/dist/meta.js +981 -0
- package/dist/resources.d.ts +215 -0
- package/dist/resources.js +856 -0
- package/dist/scaffold.d.ts +3 -4
- package/dist/scaffold.js +21 -9
- package/dist/trace.d.ts +5 -0
- package/dist/trace.js +54 -5
- package/dist/tui/app.js +19 -5
- package/dist/tui/links.d.ts +27 -0
- package/dist/tui/links.js +142 -0
- package/dist/tui/models.d.ts +3 -1
- package/dist/tui/models.js +65 -7
- package/dist/tui/sandbox.d.ts +10 -0
- package/dist/tui/sandbox.js +131 -0
- package/package.json +3 -2
- package/templates/editor/.github/copilot-instructions.md +29 -43
- package/templates/editor/.github/prompts/analyze.prompt.md +3 -1
- package/templates/editor/.github/prompts/finetune-apply.prompt.md +221 -42
- package/templates/editor/.github/prompts/project-review.prompt.md +1 -1
- package/templates/editor/.github/skills/zen-analyze-run/SKILL.md +162 -57
- package/templates/editor/.github/skills/zen-cli/references/finetune.md +74 -14
- package/templates/editor/.github/skills/zen-cli/references/inspect.md +16 -2
- package/templates/editor/.github/skills/zen-cli/references/projects.md +4 -6
- package/templates/editor/.github/skills/zen-cli/references/sandbox.md +25 -13
- package/templates/editor/.github/skills/zen-finetune/SKILL.md +74 -33
- package/templates/editor/.github/skills/zen-inspect/SKILL.md +14 -1
- package/templates/editor/.github/skills/zen-inspect-ask/SKILL.md +4 -3
- package/templates/editor/.github/skills/zen-instructions/SKILL.md +4 -12
- package/templates/editor/.github/skills/zen-memory/SKILL.md +64 -39
- package/templates/editor/.github/skills/zen-review/SKILL.md +6 -31
- package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +1 -2
- package/templates/editor/.github/skills/zen-review/scripts/review.sh +3 -12
- package/templates/editor/.github/skills/zen-sandbox/SKILL.md +2 -1
- package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +2 -4
- package/templates/project/agents/fork-instructions.md +78 -28
- package/templates/project/agents/memory-instructions.md +222 -493
- package/templates/project/agents/tools-instructions.md +7 -0
- package/templates/editor/.github/skills/zen-memory/scripts/check-instructions.sh +0 -116
|
@@ -4,496 +4,225 @@ requires: [memory]
|
|
|
4
4
|
|
|
5
5
|
# Memory
|
|
6
6
|
|
|
7
|
-
This project
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
|
32
|
-
|
|
|
33
|
-
|
|
|
34
|
-
|
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
92
|
-
|
|
93
|
-
|
|
94
|
-
|
|
95
|
-
|
|
96
|
-
|
|
97
|
-
|
|
98
|
-
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
119
|
-
|
|
120
|
-
|
|
121
|
-
|
|
122
|
-
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
|
|
132
|
-
|
|
133
|
-
|
|
134
|
-
|
|
135
|
-
`
|
|
136
|
-
|
|
137
|
-
|
|
138
|
-
|
|
139
|
-
|
|
140
|
-
|
|
141
|
-
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
149
|
-
|
|
150
|
-
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
161
|
-
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
|
|
176
|
-
|
|
177
|
-
|
|
178
|
-
|
|
179
|
-
|
|
180
|
-
|
|
181
|
-
|
|
182
|
-
|
|
183
|
-
|
|
184
|
-
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
|
|
189
|
-
|
|
190
|
-
|
|
191
|
-
|
|
192
|
-
|
|
193
|
-
|
|
194
|
-
|
|
195
|
-
|
|
196
|
-
|
|
197
|
-
|
|
198
|
-
|
|
199
|
-
|
|
200
|
-
|
|
201
|
-
|
|
202
|
-
|
|
203
|
-
|
|
204
|
-
|
|
205
|
-
|
|
206
|
-
|
|
207
|
-
|
|
208
|
-
|
|
209
|
-
|
|
210
|
-
|
|
211
|
-
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
|
|
215
|
-
|
|
216
|
-
|
|
217
|
-
|
|
218
|
-
|
|
219
|
-
|
|
220
|
-
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
|
|
226
|
-
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
| what was learned about a subject, however it was phrased | `memory_search` |
|
|
230
|
-
| a name, path, id, host, flag or command, spelled exactly | `memory_grep` |
|
|
231
|
-
| whether an exact name, path or command was written down at all | `memory_grep` |
|
|
232
|
-
| everywhere a thing is mentioned, before changing or retiring it | `memory_grep` |
|
|
233
|
-
| a starting point, when you do not yet know the vocabulary | `memory_search` |
|
|
234
|
-
|
|
235
|
-
Either way, ids from one are ids for the other: grep a name, then `memory_load`
|
|
236
|
-
what it turned up.
|
|
237
|
-
|
|
238
|
-
Recalling nothing is not proof of anything: work it out normally, then commit
|
|
239
|
-
the result so the next run does not repeat it. A `memory_grep` that found
|
|
240
|
-
nothing is stronger - it means the string is not there - but it says nothing
|
|
241
|
-
about the subject under another name.
|
|
242
|
-
|
|
243
|
-
## Updating it
|
|
244
|
-
|
|
245
|
-
Commit when **the next run would otherwise have to work this out again** and
|
|
246
|
-
working it out cost more than a `memory_load` will. The measure is what the
|
|
247
|
-
answer COST, not what kind of thing it is: one cheap tool call away, do not;
|
|
248
|
-
five reads, a fan-out and a judgement, commit the judgement and not only the
|
|
249
|
-
five paths.
|
|
250
|
-
|
|
251
|
-
| Worth committing | Not worth committing |
|
|
252
|
-
| ----------------------------------------------------------------- | ------------------------------------------------------------------- |
|
|
253
|
-
| The route through the codebase to a recurring question | A verbatim copy of one living file, which a read gives current |
|
|
254
|
-
| What a schema or docs search resolved to, and what you made of it | The ranked guesses it returned on the way there |
|
|
255
|
-
| The call or command sequence that turned out to be necessary | A single tool call that answers in milliseconds |
|
|
256
|
-
| The exact invocation that finally worked, with its directory | The request restated, or notes on progress |
|
|
257
|
-
| A working script or request body, committed whole | What running it printed - a reading, which the script gives current |
|
|
258
|
-
| An interface that behaved differently from its documentation | What a call returned, which the call gives current |
|
|
259
|
-
| The passage itself, when its source cannot change under you | A passage quoted out of something that can |
|
|
260
|
-
| A proven absence - looked here and here, it is not there | Anything not actually verified |
|
|
261
|
-
|
|
262
|
-
A restatement is not merely wasted space. Recall seeds on text alone, so a run
|
|
263
|
-
that commits its own request as a task, a plan and a result has committed three
|
|
264
|
-
near-copies of one sentence - and on the next similar question those three take
|
|
265
|
-
the seed slots between them. Everything actually learned then ranks below them
|
|
266
|
-
and is never reached.
|
|
267
|
-
|
|
268
|
-
A search over a schema or a documentation index costs a round trip and comes
|
|
269
|
-
back ranked, so it is the thing most worth not paying for twice. Commit what it
|
|
270
|
-
**resolved to** - the operation and its shape, or the document, heading and line
|
|
271
|
-
range - **and what you concluded from reading it**. The pointers alone make the
|
|
272
|
-
next run repeat the reading; the conclusion alone cannot be checked. Both, in
|
|
273
|
-
one subgraph, and the next run answers at once and verifies cheaply.
|
|
274
|
-
|
|
275
|
-
When the index is over something pinned - a released spec, a versioned reference
|
|
276
|
-
tree - go one further and carry the passage itself in a `file` node, headed with
|
|
277
|
-
the documents and line ranges it was taken from. The pointer says where to look
|
|
278
|
-
and the conclusion says what it meant, but only the passage saves the next run
|
|
279
|
-
from opening the sources to find out what they actually said. Say in the node's
|
|
280
|
-
text which kind of source it was, so a later run can see why a copy was allowed.
|
|
281
|
-
|
|
282
|
-
### When to commit
|
|
283
|
-
|
|
284
|
-
That test says what is worth keeping. It does not say when to write it down, and
|
|
285
|
-
work that is never written down cost what it cost for nothing.
|
|
286
|
-
|
|
287
|
-
Two things call for a commit while the run is still going:
|
|
288
|
-
|
|
289
|
-
- **A search came back empty, or came back beside the point, and you went on to
|
|
290
|
-
work the answer out anyway.** That gap is the next run's gap too, and you are
|
|
291
|
-
the only one in a position to close it. It is the usual reason a memory stays
|
|
292
|
-
useless: every run pays for the same answer, no run writes it down.
|
|
293
|
-
- **Something cost more than a `memory_load` will** - several reads, a fan-out,
|
|
294
|
-
a build, a long command, a delegated lookup - or produced an artifact that
|
|
295
|
-
works: a script, a query, a request body, the invocation that finally ran.
|
|
296
|
-
|
|
297
|
-
And three moments must not pass without one:
|
|
298
|
-
|
|
299
|
-
| Before | Because |
|
|
300
|
-
| -------------------------------------- | ----------------------------------------------------------------- |
|
|
301
|
-
| returning your final answer | the turn ends there, and nothing is written after it |
|
|
302
|
-
| handing off to another agent | control moves and does not come back - what you know goes with it |
|
|
303
|
-
| returning to the agent that forked you | only your answer returns; your transcript is dropped at the join |
|
|
304
|
-
|
|
305
|
-
Commit a piece of work when it is finished rather than saving all of it for one
|
|
306
|
-
call at the end: a run that is interrupted, or that runs out of room, loses
|
|
307
|
-
whatever was being held back. That is not licence to split one subgraph across
|
|
308
|
-
calls - refs resolve only within a single `memory_commit`, so whatever links
|
|
309
|
-
together is still committed together.
|
|
310
|
-
|
|
311
|
-
### How to write it down
|
|
312
|
-
|
|
313
|
-
**Commit the whole subgraph in one call.** A script with no record of what asked
|
|
314
|
-
for it, or a fact with nothing that acts on it, is a memory nobody can use. Refs
|
|
315
|
-
resolve only within a single `memory_commit`, so a subgraph split across calls
|
|
316
|
-
arrives without its links.
|
|
317
|
-
|
|
318
|
-
**Use `ref` (not `id`) for new nodes.** A new node uses `ref` as its local name
|
|
319
|
-
(for example, `"ask"`, `"script"`), and edges connect them using those refs:
|
|
320
|
-
|
|
321
|
-
```json
|
|
322
|
-
{
|
|
323
|
-
"nodes": [
|
|
324
|
-
{ "ref": "ask", "kind": "task", "text": "audit firewall rules for risky ports" },
|
|
325
|
-
{ "ref": "script", "kind": "file", "text": "risk report generator", "file": "report.py" }
|
|
326
|
-
],
|
|
327
|
-
"edges": [{ "from": "ask", "to": "script", "relation": "PRODUCED" }]
|
|
328
|
-
}
|
|
329
|
-
```
|
|
330
|
-
|
|
331
|
-
Use `id` only when updating an existing node that is already in memory from a
|
|
332
|
-
previous search or load. Never pass `id` when creating a new node, and do not
|
|
333
|
-
pass both `ref` and `id` on the same node.
|
|
334
|
-
|
|
335
|
-
**Do not re-commit what a search already returned.** A node that says what one
|
|
336
|
-
already in memory says is folded into it, and its existing id comes back under
|
|
337
|
-
your ref - so the links you asked for still land, on the memory that was already
|
|
338
|
-
there.
|
|
339
|
-
|
|
340
|
-
**Take the task text you were handed.** When your instructions give you the
|
|
341
|
-
task text, commit that text verbatim as your `task` node and look nothing up for
|
|
342
|
-
it. Agents that commit at the same moment cannot see each other; identical
|
|
343
|
-
wording is what folds their nodes into one.
|
|
344
|
-
|
|
345
|
-
**Grep for an entity before minting a node for it.** An endpoint, a command, a
|
|
346
|
-
host, a tool, a file - anything that recurs across runs is one node the rest of
|
|
347
|
-
the graph hangs off, and folding by similarity will not catch a second copy
|
|
348
|
-
worded differently. `memory_grep` the exact string first, and attach your edges
|
|
349
|
-
to what comes back. One grep per entity you are about to mint, for its exact
|
|
350
|
-
string. A sentence describing the subject is not an entity, and neither is a
|
|
351
|
-
task's text: a literal phrase misses every other wording of it, and a
|
|
352
|
-
near-duplicate is folded anyway.
|
|
353
|
-
|
|
354
|
-
A duplicated hub is worse than a missing one. It splits the graph into islands:
|
|
355
|
-
the question reaches one copy, the artifact that answers it hangs off another,
|
|
356
|
-
and the walk out from a seed cannot cross between them - so a memory that is
|
|
357
|
-
present returns nothing, and nothing in the recollection says it happened.
|
|
358
|
-
|
|
359
|
-
**Say where the content came from.** This is what lets an incomplete
|
|
360
|
-
recollection be continued instead of believed:
|
|
361
|
-
|
|
362
|
-
| The node holds | Name |
|
|
363
|
-
| ------------------------------- | ----------------------------------------------------------------------------------------------------------------------------- |
|
|
364
|
-
| A fact about this codebase | the file and the line range it was read from - `src/models/factory.ts:120-168` |
|
|
365
|
-
| Anything spanning several files | every one of them, each with its range, in the order they are read |
|
|
366
|
-
| An API route or a behaviour | the document and operation id, or the request sent and the status that came back |
|
|
367
|
-
| Something a document states | document, heading and line range, next to what it states - the pointer is how the passage is checked, not a substitute for it |
|
|
368
|
-
| Something a command established | the exact command, its arguments, and the directory it ran in |
|
|
369
|
-
| A plan | the steps, and where each step's target lives |
|
|
370
|
-
| A negative result | where you looked, so the search is not repeated |
|
|
371
|
-
|
|
372
|
-
**Write the text as the question.** Not the way the system that produced it
|
|
373
|
-
names things, and with the identifying facts first - only the first 160
|
|
374
|
-
characters appear in a recollection.
|
|
375
|
-
|
|
376
|
-
| Instead of | Write |
|
|
377
|
-
| ----------------- | ------------------------------------------------------------------------------------------ |
|
|
378
|
-
| `fix for the 409` | `A duplicate customer email returns 409, not 422 - retry is wrong (src/billing.ts:88-104)` |
|
|
379
|
-
| `retry.ts` | `Where retries are configured: one policy for all adapters, src/models/factory.ts:40-96` |
|
|
380
|
-
|
|
381
|
-
**Put the content in a file, not in the text.** This is the usual shape, not a
|
|
382
|
-
special case: a script, a config, a query, a request body, a rendered table of
|
|
383
|
-
findings, a passage worth keeping whole, an answer that took several sources to
|
|
384
|
-
assemble - all of it is a `file` node split in two. The `text` describes the
|
|
385
|
-
content and says where it came from; the file holds the content itself, whole
|
|
386
|
-
and exactly as it was - the entire block, not a summary of it. Content in a file
|
|
387
|
-
costs nothing until a `memory_load` asks for it, and comes back at
|
|
388
|
-
`/memory/<id>.<ext>` to be read or run. Commit a node with no file only when the
|
|
389
|
-
whole of what you know is one line long.
|
|
390
|
-
|
|
391
|
-
**The file must exist in the workspace first.** `memory_commit` copies an
|
|
392
|
-
existing file from the workspace; it is not an upload channel and does not
|
|
393
|
-
write file contents from raw arguments. Write the file to the workspace first
|
|
394
|
-
(using `write_file`, `apply_patch`, `copy_file`, or a command saving under
|
|
395
|
-
`/workspace`), then pass its workspace path (e.g. `"file": "report.py"` or
|
|
396
|
-
`"file": "/workspace/report.py"`). Write it with its provenance header (below)
|
|
397
|
-
the first time: adding the header in a second write pays for the whole file
|
|
398
|
-
twice.
|
|
399
|
-
|
|
400
|
-
Do not commit files from the living codebase (use a pointer with file and line
|
|
401
|
-
ranges instead - copies go stale silently), raw ephemeral command logs, or
|
|
402
|
-
anything outside the workspace.
|
|
403
|
-
|
|
404
|
-
**Name the sources inside the file as well as in the text.** The two halves
|
|
405
|
-
arrive separately - a recollection shows the text, and only a later
|
|
406
|
-
`memory_load` opens the file - so a file read on its own is an assertion with
|
|
407
|
-
nothing behind it. Open it with a header naming every document, heading and line
|
|
408
|
-
range the content came from, and when it was taken, then the content verbatim:
|
|
409
|
-
|
|
410
|
-
```markdown
|
|
411
|
-
<!-- reference-docs-1.4/overview.html.md:112-160 and
|
|
412
|
-
reference-docs-1.4/architecture.html.md:38-91
|
|
413
|
-
pinned 1.4 reference tree, read 2026-04-09 -->
|
|
414
|
-
|
|
415
|
-
...the passages, whole and unedited...
|
|
416
|
-
```
|
|
417
|
-
|
|
418
|
-
Use whatever comment form the file's own format takes. A header costs two lines
|
|
419
|
-
and is the difference between a copy that can be re-checked against its source
|
|
420
|
-
and one that can only be believed.
|
|
421
|
-
|
|
422
|
-
Make the file self-contained - it will be opened in a different workspace, so it
|
|
423
|
-
takes its inputs as arguments and reads credentials from the environment - and
|
|
424
|
-
say so in the text. **Give it a configurable output path.** `/memory` is
|
|
425
|
-
read-only: a script that writes beside itself fails, while one that takes
|
|
426
|
-
`--out` writes into the workspace and is reusable unchanged. Use a `snippet`
|
|
427
|
-
only for the few lines that are read rather than run.
|
|
428
|
-
|
|
429
|
-
A remembered script runs from where it is - the mount is readable, so
|
|
430
|
-
`python3 /memory/<id>.py` or `node /memory/<id>.js` needs no copy first:
|
|
431
|
-
|
|
432
|
-
```
|
|
433
|
-
python3 /memory/01JD9Q7X8N2K4M6P8R0T2V4W6Y.py --out ./report.csv
|
|
434
|
-
```
|
|
435
|
-
|
|
436
|
-
**Read it before running it.** It is code an earlier run wrote, recalled by
|
|
437
|
-
similarity: `memory_load` returns its contents, or its path when it is large, in
|
|
438
|
-
which case read the file. Confirm it is the thing you want, and that its
|
|
439
|
-
arguments are what you think, before executing anything.
|
|
440
|
-
|
|
441
|
-
**Commit what produces the answer, not the material it was made from.** This is
|
|
442
|
-
about what to keep, not what form to keep it in - whatever survives the test
|
|
443
|
-
still goes in a file. A file the project holds: the pointer, never a copy - a
|
|
444
|
-
copy goes stale silently and looks exactly as authoritative when it is wrong. An
|
|
445
|
-
external call: the `operation` - route, auth, the parameters that mattered, the
|
|
446
|
-
status a case returns - never the body that came back. A script: the file and
|
|
447
|
-
the invocation that worked, never its output. What a run ESTABLISHED belongs in
|
|
448
|
-
the node's text - that it works, what it was run against, the verdict that was
|
|
449
|
-
the point; the rows it emitted do not.
|
|
450
|
-
|
|
451
|
-
Two things fall outside that. An answer you assembled from several sources is a
|
|
452
|
-
copy of none of them and exists nowhere in the project, so commit it, with a
|
|
453
|
-
pointer node per source `INFORMED`ing it. And a passage from a pinned source
|
|
454
|
-
does not go stale silently, so it may be kept whole, as described for indexes
|
|
455
|
-
above.
|
|
456
|
-
|
|
457
|
-
A body or a result set may still be worth keeping as a SPECIMEN - a shape to
|
|
458
|
-
write against, a case to reproduce. Commit it as a `file` node whose text says
|
|
459
|
-
what was asked, when, and that it is what came back then, never what the data
|
|
460
|
-
is. Keep credentials out of the store, along with any personal data the specimen
|
|
461
|
-
did not need: it outlives the session and every later run can read it.
|
|
462
|
-
|
|
463
|
-
**Correct by superseding, never by editing.** Commit the new node and link it to
|
|
464
|
-
the old one with `SUPERSEDES`. Recall then stops serving the wrong answer
|
|
465
|
-
without destroying the record of why it changed.
|
|
466
|
-
|
|
467
|
-
**Ask whether it will still be true next month.** Memory has no expiry and no
|
|
468
|
-
reviewer. A durable fact about this project survives; a fact about this
|
|
469
|
-
afternoon's state is how a graph becomes confidently wrong.
|
|
470
|
-
|
|
471
|
-
### Preferences
|
|
472
|
-
|
|
473
|
-
A `preference` is a standing instruction from the user, and it is not recalled
|
|
474
|
-
like everything else: every preference you can see is rendered into a
|
|
475
|
-
`<memory-preferences>` block at the start of every later run, each with its id.
|
|
476
|
-
They apply unless that run's request contradicts them.
|
|
477
|
-
|
|
478
|
-
So commit one only when the user's own words generalise - "always", "from now
|
|
479
|
-
on", "I prefer", "never". A single request being fulfilled is not a standing
|
|
480
|
-
instruction, and one committed by mistake is in every future prompt until
|
|
481
|
-
something supersedes it.
|
|
482
|
-
|
|
483
|
-
What the user says about THEMSELVES belongs here too, and for the same reason: a
|
|
484
|
-
later run that has to ask again has already lost what the block is for. Their
|
|
485
|
-
name and how they want to be addressed, the role they work in, the timezone
|
|
486
|
-
their dates are in, which of several accounts, environments or repositories is
|
|
487
|
-
theirs, the language or the units they want answers in. Commit what they stated,
|
|
488
|
-
in their own terms - never what you inferred from how they happened to phrase a
|
|
489
|
-
request, and never a credential or a secret, which is not a preference however
|
|
490
|
-
it was offered.
|
|
491
|
-
|
|
492
|
-
To change one, commit the replacement and link it to the id shown in that block
|
|
493
|
-
with `SUPERSEDES`.
|
|
494
|
-
|
|
495
|
-
### Forgetting
|
|
496
|
-
|
|
497
|
-
Forget only what is wrong and has no successor. A superseded memory is already
|
|
498
|
-
hidden from recall and should stay for the history, so `memory_forget` is for
|
|
499
|
-
what should never have been written, not for what has been replaced.
|
|
7
|
+
This project shares a persistent graph between runs. Reach it only through the
|
|
8
|
+
`memory_*` tools. Never inspect, list, grep, or modify the store directly.
|
|
9
|
+
|
|
10
|
+
Use only the capabilities you hold. If `memory_commit` is absent, do not update
|
|
11
|
+
the graph. If `memory_forget` is absent, do not remove nodes.
|
|
12
|
+
|
|
13
|
+
Memory exists to avoid paying twice for durable work. Reuse and verify useful
|
|
14
|
+
prior work; do not treat the graph as an authority or a store for current API
|
|
15
|
+
results.
|
|
16
|
+
|
|
17
|
+
## Read
|
|
18
|
+
|
|
19
|
+
Search before starting work that costs more than one cheap read or call:
|
|
20
|
+
|
|
21
|
+
- On request arrival, search for the question before planning.
|
|
22
|
+
- On handoff or fork arrival, search for the brief you received.
|
|
23
|
+
- Before a substantial investigation, search for the question it would answer.
|
|
24
|
+
- At a dead end, search for the newly identified missing fact.
|
|
25
|
+
|
|
26
|
+
Do not repeat the same search in different words. Search again only when the
|
|
27
|
+
question has changed.
|
|
28
|
+
|
|
29
|
+
### Choose the retrieval tool
|
|
30
|
+
|
|
31
|
+
| Need | Tool |
|
|
32
|
+
| ---------------------------------------------- | --------------- |
|
|
33
|
+
| A subject, however it was phrased | `memory_search` |
|
|
34
|
+
| A known name, path, id, host, flag, or command | `memory_grep` |
|
|
35
|
+
| Every occurrence of an exact string | `memory_grep` |
|
|
36
|
+
| The complete content of a returned node | `memory_load` |
|
|
37
|
+
|
|
38
|
+
Use `memory_search` with the complete natural-language question. Narrow broad
|
|
39
|
+
results with `kinds`, `newer_than`, `limit`, `max_hops`, or `max_nodes`.
|
|
40
|
+
|
|
41
|
+
Never use `memory_grep` as a generic first lookup or after an empty semantic
|
|
42
|
+
search. An empty `memory_search` means no semantic match was recalled, not that
|
|
43
|
+
the subject is absent. An empty `memory_grep` establishes only that the exact
|
|
44
|
+
string is absent.
|
|
45
|
+
|
|
46
|
+
Load every node you will rely on. Search results contain clipped descriptions,
|
|
47
|
+
not complete node contents.
|
|
48
|
+
|
|
49
|
+
### Read recollections as graphs
|
|
50
|
+
|
|
51
|
+
A `<memory-recollection>` is an outline of nodes and relations, not a ranked
|
|
52
|
+
list; the indentation is the graph. A root line reads `score kind id`; a root
|
|
53
|
+
the walk reached without matching carries `--` instead of a score. An indented
|
|
54
|
+
line is a connected node, prefixed by its relation: `→produced` means the line
|
|
55
|
+
above produced it, `←informed` means it informed the line above.
|
|
56
|
+
`PRODUCED`, `CALLS`, and `SUPERSEDES` form the reusable work; `INFORMED` adds
|
|
57
|
+
background. A `+` reference points to an id already shown above.
|
|
58
|
+
|
|
59
|
+
Node text is clipped to 160 characters. A file node adds one line with its
|
|
60
|
+
`/memory/<id>.<ext>` path, size, and use count. Use `memory_load` to obtain the
|
|
61
|
+
complete node and its usable path. Touch only paths returned by a `memory_*`
|
|
62
|
+
tool.
|
|
63
|
+
|
|
64
|
+
Direct store access is prohibited because it bypasses audience controls, may
|
|
65
|
+
serve superseded nodes, does not record use, and can race with another writer.
|
|
66
|
+
|
|
67
|
+
### Verify before reuse
|
|
68
|
+
|
|
69
|
+
- For a pinned release, versioned specification, or immutable document, verify
|
|
70
|
+
that the recorded source still resolves.
|
|
71
|
+
- For code, APIs, commands, and other living sources, verify the cited location,
|
|
72
|
+
route, or invocation still behaves as recorded.
|
|
73
|
+
- Redo the investigation only when that cheap check fails or the cost of being
|
|
74
|
+
wrong justifies it.
|
|
75
|
+
|
|
76
|
+
Read a remembered script before running it. Confirm its purpose, arguments,
|
|
77
|
+
inputs, outputs, and credentials handling.
|
|
78
|
+
|
|
79
|
+
### Keep memory out of ordinary answers
|
|
80
|
+
|
|
81
|
+
Report findings and checkable sources, not the mechanism that found them. Do
|
|
82
|
+
not expose `/memory` paths, node ids, or say that something was recalled or
|
|
83
|
+
remembered. The exception is a request about the store itself, where ids and
|
|
84
|
+
memory state are the subject.
|
|
85
|
+
|
|
86
|
+
## Keep only durable value
|
|
87
|
+
|
|
88
|
+
Commit something only when the next run would otherwise have to do meaningful
|
|
89
|
+
work again and the result should still be valid next month.
|
|
90
|
+
|
|
91
|
+
Keep:
|
|
92
|
+
|
|
93
|
+
- A route, call, command, or invocation that retrieves a current answer.
|
|
94
|
+
- A conclusion assembled from several sources, with every source named.
|
|
95
|
+
- A proven absence, with the complete search boundary named.
|
|
96
|
+
- A reusable plan, request body, query, or verified script.
|
|
97
|
+
- A passage copied from an immutable, pinned source, with provenance.
|
|
98
|
+
|
|
99
|
+
Do not keep:
|
|
100
|
+
|
|
101
|
+
- Raw user input, progress notes, or a restatement of the request.
|
|
102
|
+
- A value available from one cheap current call.
|
|
103
|
+
- Live API results, inventories, counts, or raw command output.
|
|
104
|
+
- Unverified, failed, partial, or speculative work.
|
|
105
|
+
- A copy of a living project file that will silently become stale.
|
|
106
|
+
- A duplicate of a node already returned by search.
|
|
107
|
+
|
|
108
|
+
Remember the route when the answer is cheap and current. Remember the supported
|
|
109
|
+
conclusion when deriving it is expensive. Remember the script, never what its
|
|
110
|
+
last run printed.
|
|
111
|
+
|
|
112
|
+
## Write the graph
|
|
113
|
+
|
|
114
|
+
A node is one reusable thing. Its `text` is how it is found; an optional file
|
|
115
|
+
holds content too large for one line.
|
|
116
|
+
|
|
117
|
+
| Kind | Use |
|
|
118
|
+
| ------------ | ------------------------------------------------------ |
|
|
119
|
+
| `task` | The request that initiated the work |
|
|
120
|
+
| `plan` | A reusable approach that worked |
|
|
121
|
+
| `fact` | A durable truth with provenance |
|
|
122
|
+
| `snippet` | A few lines intended to be read |
|
|
123
|
+
| `file` | A complete reusable artifact |
|
|
124
|
+
| `operation` | An endpoint, command, or query that was used |
|
|
125
|
+
| `preference` | A standing instruction or user fact stated by the user |
|
|
126
|
+
|
|
127
|
+
| Relation | Meaning |
|
|
128
|
+
| ------------ | ---------------------------------------- |
|
|
129
|
+
| `PRODUCED` | The source produced the target |
|
|
130
|
+
| `CALLS` | The source invokes the target |
|
|
131
|
+
| `SUPERSEDES` | The source replaces the stale target |
|
|
132
|
+
| `INFORMED` | The source was background for the target |
|
|
133
|
+
|
|
134
|
+
Put required reusable work on the `PRODUCED`, `CALLS`, or `SUPERSEDES` spine.
|
|
135
|
+
Use `INFORMED` only for background that may be omitted under a tight recall
|
|
136
|
+
budget. Direct `INFORMED` from the background fact to the work it informed.
|
|
137
|
+
|
|
138
|
+
### Commit at the right time
|
|
139
|
+
|
|
140
|
+
Commit finished durable work as soon as it is verified. Do not pass any of
|
|
141
|
+
these points with uncommitted reusable work:
|
|
142
|
+
|
|
143
|
+
- Before a final answer.
|
|
144
|
+
- Before a handoff, because control does not return automatically.
|
|
145
|
+
- Before returning from a fork, because only the branch answer rejoins.
|
|
146
|
+
|
|
147
|
+
Commit one connected subgraph in one `memory_commit`. Refs resolve only inside
|
|
148
|
+
that call; splitting connected nodes across calls loses their links.
|
|
149
|
+
|
|
150
|
+
### Create nodes correctly
|
|
151
|
+
|
|
152
|
+
- Use `ref` as the local name for every new node.
|
|
153
|
+
- Use `id` only for an existing node returned by search or load.
|
|
154
|
+
- Never set both `ref` and `id` on one node.
|
|
155
|
+
- Link the task to what it produced and link artifacts to operations they call.
|
|
156
|
+
- When instructions supply canonical task text, use it verbatim so parallel
|
|
157
|
+
commits fold together.
|
|
158
|
+
- Do not recommit a node that search already returned; link to its existing id.
|
|
159
|
+
|
|
160
|
+
Before creating a recurring entity node such as an endpoint, command, host,
|
|
161
|
+
tool, or file, use `memory_grep` for its exact string. Reuse the existing id
|
|
162
|
+
when found. Do not grep prose subjects or task text merely to avoid semantic
|
|
163
|
+
near-duplicates; normal folding handles those.
|
|
164
|
+
|
|
165
|
+
Write node text as the question a future user will ask. Put identifying facts
|
|
166
|
+
first because recall shows only the first 160 characters. Keep the text short;
|
|
167
|
+
put substantial content in a file node.
|
|
168
|
+
|
|
169
|
+
### Record provenance
|
|
170
|
+
|
|
171
|
+
Every durable claim must name how it can be checked:
|
|
172
|
+
|
|
173
|
+
- Codebase fact: file and line range.
|
|
174
|
+
- Multi-file conclusion: every file and range used.
|
|
175
|
+
- API behavior: document and operation id, or request and returned status.
|
|
176
|
+
- Document fact: document, heading, and opened line range.
|
|
177
|
+
- Command result: exact command, arguments, and working directory.
|
|
178
|
+
- Negative result: every location and query checked.
|
|
179
|
+
|
|
180
|
+
A pointer without a conclusion makes the next run repeat the reading. A
|
|
181
|
+
conclusion without a pointer cannot be checked. Store both.
|
|
182
|
+
|
|
183
|
+
### Commit files safely
|
|
184
|
+
|
|
185
|
+
Use a file node for scripts, configurations, request bodies, substantial
|
|
186
|
+
answers, multi-source findings, and passages from pinned sources. The node text
|
|
187
|
+
describes what the file does and its provenance; the file holds the complete
|
|
188
|
+
content.
|
|
189
|
+
|
|
190
|
+
The source file must already exist under `/workspace`. `memory_commit` copies
|
|
191
|
+
it; it does not accept file contents. Never commit files outside the workspace,
|
|
192
|
+
raw logs, live result sets, credentials, unnecessary personal data, or copies
|
|
193
|
+
of living project files.
|
|
194
|
+
|
|
195
|
+
Put provenance in the file itself as a short header. Make executable artifacts
|
|
196
|
+
self-contained, take request-specific values as arguments, read credentials
|
|
197
|
+
from the environment, and accept an output path under `/workspace`. The
|
|
198
|
+
`/memory` mount is read-only.
|
|
199
|
+
|
|
200
|
+
Commit a script only after it ran successfully against the intended environment
|
|
201
|
+
and produced verified output. Commit its invocation and operations, not its
|
|
202
|
+
output. When reusing a remembered script, run it from the path returned by
|
|
203
|
+
`memory_load` only after reading it.
|
|
204
|
+
|
|
205
|
+
A response body or result set may be kept only as an explicit specimen for
|
|
206
|
+
development or reproduction. Its text must say what was requested, when it was
|
|
207
|
+
captured, and that it is historical output rather than a current fact.
|
|
208
|
+
|
|
209
|
+
### Correct and replace
|
|
210
|
+
|
|
211
|
+
Never edit an existing memory as though its old claim had always been correct.
|
|
212
|
+
Commit the replacement and connect it to the old node with `SUPERSEDES`. Recall
|
|
213
|
+
then hides the stale node while preserving the history.
|
|
214
|
+
|
|
215
|
+
## Preferences
|
|
216
|
+
|
|
217
|
+
Use `preference` only for a standing instruction or personal fact the user
|
|
218
|
+
explicitly states: wording such as "always", "from now on", "I prefer", or
|
|
219
|
+
"never". Do not infer a preference from one request and never store a secret.
|
|
220
|
+
|
|
221
|
+
Preferences appear in every later prompt. Replace one by committing the new
|
|
222
|
+
preference with a `SUPERSEDES` edge to the old id.
|
|
223
|
+
|
|
224
|
+
## Forget
|
|
225
|
+
|
|
226
|
+
Use `memory_forget` only for information that should never have been stored and
|
|
227
|
+
has no valid successor. Do not forget a corrected node: superseding already
|
|
228
|
+
hides it and preserves why the correction happened.
|