@zenera/cli 1.1.23 → 1.1.25

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (184) hide show
  1. package/README.md +88 -2
  2. package/dist/ask.d.ts +51 -0
  3. package/dist/ask.js +166 -0
  4. package/dist/banner.js +2 -2
  5. package/dist/batch.d.ts +83 -0
  6. package/dist/batch.js +413 -0
  7. package/dist/catalog.d.ts +11 -1
  8. package/dist/catalog.js +80 -7
  9. package/dist/command.d.ts +6 -0
  10. package/dist/commands/inspect.d.ts +57 -0
  11. package/dist/commands/inspect.js +539 -91
  12. package/dist/commands/list.js +128 -19
  13. package/dist/commands/memory.js +461 -32
  14. package/dist/commands/meta.js +311 -21
  15. package/dist/commands/models.js +110 -14
  16. package/dist/commands/open.js +4 -4
  17. package/dist/commands/run.js +175 -36
  18. package/dist/commands/sandbox.js +148 -15
  19. package/dist/engine.d.ts +24 -0
  20. package/dist/engine.js +61 -8
  21. package/dist/eventlog.d.ts +59 -0
  22. package/dist/eventlog.js +146 -0
  23. package/dist/liveness.d.ts +7 -0
  24. package/dist/liveness.js +20 -3
  25. package/dist/main.js +5 -2
  26. package/dist/meta/editor.d.ts +9 -0
  27. package/dist/meta/editor.js +60 -0
  28. package/dist/meta/finetune/children.d.ts +8 -0
  29. package/dist/meta/finetune/children.js +76 -0
  30. package/dist/meta/finetune/command.d.ts +30 -0
  31. package/dist/meta/finetune/command.js +338 -0
  32. package/dist/meta/finetune/dataset/anchors.d.ts +41 -0
  33. package/dist/meta/finetune/dataset/anchors.js +239 -0
  34. package/dist/meta/finetune/dataset/changes.d.ts +36 -0
  35. package/dist/meta/finetune/dataset/changes.js +319 -0
  36. package/dist/meta/finetune/dataset/command.d.ts +17 -0
  37. package/dist/meta/finetune/dataset/command.js +1011 -0
  38. package/dist/meta/finetune/dataset/drift.d.ts +33 -0
  39. package/dist/meta/finetune/dataset/drift.js +71 -0
  40. package/dist/meta/finetune/dataset/export.d.ts +26 -0
  41. package/dist/meta/finetune/dataset/export.js +51 -0
  42. package/dist/meta/finetune/dataset/index.d.ts +2 -0
  43. package/dist/meta/finetune/dataset/index.js +2 -0
  44. package/dist/meta/finetune/dataset/sample.d.ts +50 -0
  45. package/dist/meta/finetune/dataset/sample.js +197 -0
  46. package/dist/meta/finetune/dataset/schema.d.ts +33 -0
  47. package/dist/meta/finetune/dataset/schema.js +216 -0
  48. package/dist/meta/finetune/dataset/store.d.ts +35 -0
  49. package/dist/meta/finetune/dataset/store.js +177 -0
  50. package/dist/meta/finetune/dataset/types.d.ts +125 -0
  51. package/dist/meta/finetune/dataset/types.js +39 -0
  52. package/dist/meta/finetune/failure.d.ts +15 -0
  53. package/dist/meta/finetune/failure.js +26 -0
  54. package/dist/meta/finetune/feedback.d.ts +45 -0
  55. package/dist/meta/finetune/feedback.js +85 -0
  56. package/dist/meta/finetune/improvements.d.ts +51 -0
  57. package/dist/meta/finetune/improvements.js +244 -0
  58. package/dist/meta/finetune/index.d.ts +2 -0
  59. package/dist/meta/finetune/index.js +2 -0
  60. package/dist/meta/finetune/journal.d.ts +35 -0
  61. package/dist/meta/finetune/journal.js +135 -0
  62. package/dist/meta/finetune/live.d.ts +74 -0
  63. package/dist/meta/finetune/live.js +226 -0
  64. package/dist/meta/finetune/loop.d.ts +3 -0
  65. package/dist/meta/finetune/loop.js +114 -0
  66. package/dist/meta/finetune/memories.d.ts +47 -0
  67. package/dist/meta/finetune/memories.js +154 -0
  68. package/dist/meta/finetune/report.d.ts +33 -0
  69. package/dist/meta/finetune/report.js +1284 -0
  70. package/dist/meta/finetune/retry.d.ts +24 -0
  71. package/dist/meta/finetune/retry.js +96 -0
  72. package/dist/meta/finetune/sampler.d.ts +18 -0
  73. package/dist/meta/finetune/sampler.js +41 -0
  74. package/dist/meta/finetune/system.d.ts +27 -0
  75. package/dist/meta/finetune/system.js +132 -0
  76. package/dist/meta/finetune/train.d.ts +39 -0
  77. package/dist/meta/finetune/train.js +391 -0
  78. package/dist/meta/finetune/tui.d.ts +16 -0
  79. package/dist/meta/finetune/tui.js +291 -0
  80. package/dist/meta/finetune/tuning.d.ts +167 -0
  81. package/dist/meta/finetune/tuning.js +289 -0
  82. package/dist/meta/finetune/usage.d.ts +62 -0
  83. package/dist/meta/finetune/usage.js +225 -0
  84. package/dist/meta/host.d.ts +14 -0
  85. package/dist/meta/host.js +20 -0
  86. package/dist/meta/index.d.ts +11 -0
  87. package/dist/meta/index.js +11 -0
  88. package/dist/meta/launch.d.ts +81 -0
  89. package/dist/meta/launch.js +286 -0
  90. package/dist/meta/model.d.ts +44 -0
  91. package/dist/meta/model.js +119 -0
  92. package/dist/meta/prompts.d.ts +18 -0
  93. package/dist/meta/prompts.js +61 -0
  94. package/dist/meta/relay.d.ts +20 -0
  95. package/dist/meta/relay.js +123 -0
  96. package/dist/meta/tokens.d.ts +52 -0
  97. package/dist/meta/tokens.js +226 -0
  98. package/dist/meta/window.d.ts +61 -0
  99. package/dist/meta/window.js +198 -0
  100. package/dist/meta/wire.d.ts +42 -0
  101. package/dist/meta/wire.js +129 -0
  102. package/dist/modelref.d.ts +16 -0
  103. package/dist/modelref.js +41 -0
  104. package/dist/narrate.js +5 -2
  105. package/dist/podman.d.ts +42 -0
  106. package/dist/podman.js +198 -5
  107. package/dist/progress.d.ts +33 -0
  108. package/dist/progress.js +402 -0
  109. package/dist/projects.d.ts +0 -5
  110. package/dist/projects.js +2 -15
  111. package/dist/request.d.ts +45 -0
  112. package/dist/request.js +300 -0
  113. package/dist/sandbox.d.ts +2 -0
  114. package/dist/sandbox.js +20 -3
  115. package/dist/scaffold.d.ts +15 -6
  116. package/dist/scaffold.js +5 -60
  117. package/dist/session.d.ts +26 -1
  118. package/dist/session.js +46 -32
  119. package/dist/term.d.ts +5 -0
  120. package/dist/term.js +28 -3
  121. package/dist/trace.d.ts +84 -0
  122. package/dist/trace.js +737 -0
  123. package/dist/tui/models.d.ts +33 -0
  124. package/dist/tui/models.js +389 -0
  125. package/dist/tui/wrap.d.ts +5 -0
  126. package/dist/tui/wrap.js +12 -0
  127. package/dist/usage.d.ts +78 -0
  128. package/dist/usage.js +51 -0
  129. package/dist/validate.js +25 -3
  130. package/package.json +3 -2
  131. package/templates/editor/.github/copilot-instructions.md +41 -107
  132. package/templates/editor/.github/prompts/analyze.prompt.md +31 -0
  133. package/templates/editor/.github/prompts/dataset.prompt.md +108 -0
  134. package/templates/editor/.github/prompts/finetune-apply.prompt.md +91 -0
  135. package/templates/editor/.github/prompts/finetune.prompt.md +744 -0
  136. package/templates/editor/.github/prompts/new-agent.prompt.md +3 -1
  137. package/templates/editor/.github/prompts/new-skill.prompt.md +2 -0
  138. package/templates/editor/.github/prompts/project-review.prompt.md +4 -3
  139. package/templates/editor/.github/skills/zen-analyze-run/SKILL.md +483 -0
  140. package/templates/editor/.github/skills/zen-cli/SKILL.md +18 -4
  141. package/templates/editor/.github/skills/zen-cli/references/check.md +7 -5
  142. package/templates/editor/.github/skills/zen-cli/references/dataset.md +34 -0
  143. package/templates/editor/.github/skills/zen-cli/references/finetune.md +77 -0
  144. package/templates/editor/.github/skills/zen-cli/references/inspect.md +300 -21
  145. package/templates/editor/.github/skills/zen-cli/references/memory.md +121 -28
  146. package/templates/editor/.github/skills/zen-cli/references/meta.md +61 -0
  147. package/templates/editor/.github/skills/zen-cli/references/models.md +6 -2
  148. package/templates/editor/.github/skills/zen-cli/references/projects.md +12 -5
  149. package/templates/editor/.github/skills/zen-cli/references/rag.md +24 -6
  150. package/templates/editor/.github/skills/zen-cli/references/run.md +201 -4
  151. package/templates/editor/.github/skills/zen-cli/references/sandbox.md +10 -1
  152. package/templates/editor/.github/skills/zen-code-python/SKILL.md +123 -0
  153. package/templates/editor/.github/skills/zen-code-python/references/code_python.md +48 -0
  154. package/templates/editor/.github/skills/zen-dataset/SKILL.md +253 -0
  155. package/templates/editor/.github/skills/zen-finetune/SKILL.md +1791 -0
  156. package/templates/editor/.github/skills/zen-finetune/references/readme-template.md +268 -0
  157. package/templates/editor/.github/skills/zen-finetune/scripts/batch.mjs +390 -0
  158. package/templates/editor/.github/skills/zen-finetune/scripts/difficult.mjs +243 -0
  159. package/templates/editor/.github/skills/zen-finetune/scripts/memory.mjs +280 -0
  160. package/templates/editor/.github/skills/zen-finetune/scripts/next.mjs +398 -0
  161. package/templates/editor/.github/skills/zen-finetune/scripts/report.mjs +797 -0
  162. package/templates/editor/.github/skills/zen-finetune/scripts/select.mjs +354 -0
  163. package/templates/editor/.github/skills/zen-finetune/scripts/usage.mjs +722 -0
  164. package/templates/editor/.github/skills/zen-inspect/SKILL.md +431 -0
  165. package/templates/editor/.github/skills/zen-inspect-ask/SKILL.md +270 -0
  166. package/templates/editor/.github/skills/zen-memory/SKILL.md +78 -29
  167. package/templates/editor/.github/skills/zen-memory-warmup/SKILL.md +363 -531
  168. package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +20 -8
  169. package/templates/editor/.github/skills/zen-review/SKILL.md +5 -3
  170. package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +5 -4
  171. package/templates/editor/.github/skills/zen-sandbox/SKILL.md +25 -2
  172. package/templates/editor/.github/skills/zen-sandbox-capacity/SKILL.md +334 -0
  173. package/templates/editor/.github/skills/zen-sandbox-capacity/references/loadtest.md +181 -0
  174. package/templates/editor/.github/skills/zen-sandbox-capacity/scripts/preflight_sandbox.sh +457 -0
  175. package/templates/editor/.github/skills/zen-topology/SKILL.md +283 -0
  176. package/templates/editor/.vscode/agents.schema.json +1 -1
  177. package/templates/editor/.vscode/settings.json +2 -0
  178. package/templates/project/agents/files-instructions.md +35 -13
  179. package/templates/project/agents/fork-instructions.md +27 -0
  180. package/templates/project/agents/memory-instructions.md +106 -34
  181. package/templates/project/agents/tools-instructions.md +7 -4
  182. package/templates/project/gitignore +5 -0
  183. package/dist/meta.d.ts +0 -221
  184. package/dist/meta.js +0 -684
@@ -0,0 +1,270 @@
1
+ ---
2
+ name: zen-inspect-ask
3
+ description: 'Use when formulating a question for `zen inspect ask` about an `llm_call` node of a recorded Zenera run - especially a "why did you NOT do X" question (why no `memory_search` first, why no `fork` for independent research branches, why no skill, why no test run). Covers choosing the node, ruling out missing tools before asking, wording the counterfactual so the answer quotes the instruction that blocked the better behaviour, and verifying that quote against the recorded request.'
4
+ ---
5
+
6
+ # Asking a run why it did not do the better thing
7
+
8
+ `zen inspect ask` replays one recorded `llm_call` - its system prompt, messages
9
+ and tool schemas, byte for byte - with tool calling off and a preamble that
10
+ permits the model to quote its own instructions. Load **zen-inspect** for the
11
+ mechanics (graph, node, flags). This skill is about the one thing that decides
12
+ whether the call is worth its cost: **the question**.
13
+
14
+ The goal of every question here is the same: **find the sentence in the
15
+ assembled prompt that prevented the good behaviour**, or prove that no sentence
16
+ asked for it. That sentence is what you are about to edit. An answer that does
17
+ not name one is a wasted call.
18
+
19
+ Non-interactive rule, as in zen-inspect: always pass the node, the question and
20
+ the run. The question is always a file (section 3):
21
+
22
+ ```sh
23
+ zen inspect ask <llm-node-id> --question-file <question file> --dir <run-dir>
24
+ ```
25
+
26
+ Each non-interactive call is a **fresh replay**. It does not remember your
27
+ previous question. A follow-up must restate what it builds on.
28
+
29
+ ## 1. Rule out the cheap causes first
30
+
31
+ A "why didn't you" question is only about instructions if the model could have
32
+ done it. Check these from the graph and the node before spending a model call -
33
+ each one is a finding on its own, and asking the model about it produces an
34
+ invented rationale.
35
+
36
+ | Check | How | If it fails, the cause is |
37
+ | -------------------------------------- | --------------------------------------------------------------------------------------- | -------------------------------------------------- |
38
+ | The tool was offered on that call | grep the recorded request for its schema (below) | `agents.yaml` - tool not granted, or depth cap hit |
39
+ | The instruction file was in the prompt | the `system_prompt` label lists files: `fork-instructions.md`, `memory-instructions.md` | missing file, or its `requires:` not met |
40
+ | The skill was loaded | a `load_skills` node naming it, or the skill index in `request` | binding in `agents.yaml` (`skills:`) |
41
+ | Memory was already recalled for it | a `memory_recall` node before the call; `recall 0 nodes` | memory content, not behaviour |
42
+ | The context still held what it needed | no `compaction` before the node, or the item is not `hidden by` one | compaction, not instructions |
43
+
44
+ ```sh
45
+ zen inspect node n9 --part request --dir <run-dir> | grep -oE '"name": *"(fork|memory_search|memory_grep)"' | sort -u
46
+ ```
47
+
48
+ Only when every row passes is the question "which instruction stopped you".
49
+
50
+ ## 2. Pick the node where the decision was made
51
+
52
+ The replay ends at the chosen node: the model sees everything up to and
53
+ including that call's own answer, and **nothing after it**. So ask the call that
54
+ made the choice, not the one where the consequence showed up.
55
+
56
+ | Missing behaviour | Ask the `llm_call` that... |
57
+ | ------------------------------- | ----------------------------------------------------------------------------------- |
58
+ | never searched memory | issued the first tool call of the task (usually the first `llm` after `user input`) |
59
+ | ran independent work in series | issued the **first** of the sequential calls - it already had the whole plan |
60
+ | never loaded / followed a skill | chose the substitute action (the `python -c`, the hand-rolled grep) |
61
+ | handed off too early | carries `calls transfer_to_<name>` |
62
+ | gave up / answered too early | the last `llm` before `final output` |
63
+ | repeated a failed call | the one right after the first `ERROR` result |
64
+
65
+ If the choice repeated (four serial searches), ask **once**, not per step. Ask
66
+ the first call when the question is why it started that way - it already had
67
+ the whole plan. Ask the last call of the sequence when the question is about
68
+ the sequence as a whole - its replay holds every step. Never ask a middle one:
69
+ that gets "I was continuing the pattern I had started", which names no
70
+ instruction.
71
+
72
+ ## 3. Formulate the question
73
+
74
+ ### What the replayed model can see
75
+
76
+ The model you are asking sees **only its own raw context** at that call: the
77
+ system prompt, the messages up to that point, the tool descriptions, and the
78
+ answer it gave - its text and its tool calls. That is all. So:
79
+
80
+ - **No node ids, no graph words.** `n7`, `llm_call`, `tool_result`, "branch
81
+ n12" are your index, not its world. Name what it did by its content: "you
82
+ ran `grep -rn invoice /workspace/src`", "your first tool call was
83
+ `read_file` on `src/export.ts`".
84
+ - **Refer to earlier steps by what they were**, as it saw them in its
85
+ messages: "after `memory_search` returned the export node", "after the
86
+ third `run_command` failed with exit code 1".
87
+ - **Describe anything after the call yourself, in plain words.** The replay
88
+ ends at that call; it cannot see what followed. "You then searched three
89
+ more topics one after another" is something it can only learn from you.
90
+
91
+ ### What the preamble already does
92
+
93
+ `ask` puts a preamble in front of the replayed system prompt, and it already
94
+ makes the model do the following:
95
+
96
+ - cite every reason as `[<kind>: <name> › <heading or parameter>] "<verbatim quote>"`,
97
+ where kind is system prompt, skill, tool description or message
98
+ - trace the decision: the options it could see, which one it took, and which
99
+ text tipped it
100
+ - say which instruction it followed, which it missed, which two conflicted, and
101
+ any exception it judged to apply
102
+ - write "no instruction — my own default" instead of making up a source
103
+ - use the answer format the question asks for
104
+
105
+ **Do not restate any of that in the question.** Asking again for verbatim
106
+ quotes or sources adds a second, differently worded copy of the rule, and the
107
+ model follows whichever it read last.
108
+
109
+ ### The three parts
110
+
111
+ The question supplies only what the preamble cannot know. Leave a part out and
112
+ the answer drifts to a generic apology.
113
+
114
+ 1. **What it did, by content.** The action as it appears in its own answer,
115
+ stated as a fact, not an accusation.
116
+ 2. **Why not the better action - asked directly.** "Why didn't you use
117
+ `memory_search` to look up the invoice export first?" Name the action
118
+ concretely - the tool as it appears in its tool list, and the arguments or
119
+ branches it could have used - and say it was available. Never ask "did you
120
+ consider...": its own answer already shows it did not take that path, and
121
+ the question invites a yes that explains nothing.
122
+ 3. **A fixed answer shape.** So answers can be compared across calls and
123
+ runs, and so an answer without a citation is visibly empty. The shape uses
124
+ the preamble's citation form.
125
+
126
+ Write the question to a file with your file-editing tool, then hand `zen` the
127
+ file. The shell never parses the question, so quotes, apostrophes, backticks and
128
+ `$` arrive as written. End the file with this shape, verbatim:
129
+
130
+ ```text
131
+ <the question>
132
+
133
+ Answer in this shape:
134
+ options: <what you could see at that point, and which one you took>
135
+ steered-by: [<kind>: <name> › <heading or parameter>] "<quote>" (one per line, or: no instruction — my own default)
136
+ should-have-applied: [<kind>: <name> › <heading or parameter>] "<quote>" (or: none found)
137
+ exception: [<kind>: <name> › <heading or parameter>] "<quote>" (or: none)
138
+ conflict: <the two citations that pulled in different directions, or: none>
139
+ missing: <the sentence that, added where, would have made you do it>
140
+ ```
141
+
142
+ ```sh
143
+ zen inspect ask n9 --question-file .tmp/ask/<run-id>/n9-memory.md --dir <run-dir>
144
+ ```
145
+
146
+ - One file per question, at `.tmp/ask/<run-id>/<node>-<topic>.md`. `.tmp/` is
147
+ the project's git-ignored scratch.
148
+ - `--question-file` is the only way the question reaches `zen`. Never a quoted
149
+ argument, a heredoc, `$(cat ...)`, or a Python or Node script around `zen`.
150
+ - A retry (section 5, step 1) or a second opinion (step 4) reuses the same
151
+ file: add `--model <ref>` and change nothing else.
152
+
153
+ ### Wording rules
154
+
155
+ - **Ask why not, directly.** "Why didn't you fork the four lookups?" - not
156
+ "did you consider forking?", not "would forking have been better?".
157
+ - **Do not lead.** "Didn't fork-instructions tell you to parallelise?" gets
158
+ "yes, I should have" - agreement, not a cause. Name the action, never the
159
+ instruction you suspect.
160
+ - **Do not ask what it should have done.** That produces a lecture on best
161
+ practice written from general knowledge, not from its prompt.
162
+ - **One behaviour per question.** Memory and forking in one question get one
163
+ shallow answer each. Ask twice.
164
+ - **Name the alternative as an action, not a virtue.** "Why didn't you
165
+ `memory_search` for 'invoice export endpoint'?" - not "why weren't you more
166
+ efficient?".
167
+ - **Keep the exception line.** A rule with an escape hatch ("unless...", "only
168
+ when...", "for simple tasks...") is the most common blocker. The preamble asks
169
+ for exceptions, but a model will not volunteer that it granted itself one
170
+ unless an empty `exception:` line is waiting for it.
171
+
172
+ ## 4. Templates
173
+
174
+ The question bodies below replace `<the question>` in the file of section 3.
175
+ Replace every command, tool argument and topic with the run's own. None of them
176
+ mentions a node id: the id goes on the command line, never in the question.
177
+
178
+ ### Did not use memory
179
+
180
+ ```text
181
+ Your first step for this task was run_command `grep -rn 'export' /workspace/src`.
182
+ Why didn't you use memory_search or memory_grep to look up the invoice export
183
+ endpoint first? Both are in your tool list, and an earlier run may already have
184
+ worked it out. What in your instructions, or missing from them, made the
185
+ workspace the first place to look?
186
+ ```
187
+
188
+ ### Recalled memory, then redid the work
189
+
190
+ ```text
191
+ memory_search returned a node describing the invoice export endpoint and where
192
+ it is implemented. Your next step was to grep the workspace for the same
193
+ endpoint. Why didn't you use what memory returned, or memory_load that node to
194
+ read it whole? What made the recalled text not enough?
195
+ ```
196
+
197
+ ### Did not save what it learned
198
+
199
+ ```text
200
+ To answer this you read eleven files and ran four commands, and your answer
201
+ names facts a later run would need again. memory_commit is in your tool list.
202
+ Why didn't you commit what you worked out before answering?
203
+ ```
204
+
205
+ ### Did not fork independent research
206
+
207
+ ```text
208
+ From this point you researched four things one after another: (A) the auth
209
+ flow, (B) the billing schema, (C) the retry policy, (D) the webhook format.
210
+ None of the later lookups used an earlier result. Why didn't you call fork once
211
+ with a branch for each of A-D? fork is in your tool list.
212
+ ```
213
+
214
+ ### Did not follow a loaded skill
215
+
216
+ ```text
217
+ You called run_command with `python3 -c` to check the output. The skill
218
+ run-tests is in your context and says to run `npm test`. Why didn't you run
219
+ `npm test`? What made the inline script look acceptable here?
220
+ ```
221
+
222
+ ### Misused a tool
223
+
224
+ ```text
225
+ You called memory_commit three times with a `refs` array naming nodes from an
226
+ earlier commit, and each call failed. Why did you expect refs to reach nodes
227
+ committed earlier? Which words in the memory_commit description led you there,
228
+ or what was missing from it?
229
+ ```
230
+
231
+ The same skeleton covers any missing behaviour: **what it did, by content ->
232
+ why not the better action, available -> shape.** The preamble does the rest.
233
+
234
+ ## 5. Verify the answer
235
+
236
+ The answer is testimony. It is useful because it points at a sentence; it is
237
+ only a finding once the sentence is confirmed.
238
+
239
+ 1. **Grep each quote in the recorded request** - the text between the double
240
+ quotes of each `[...] "..."` citation.
241
+ ```sh
242
+ zen inspect node n9 --part request --dir <run-dir> | grep -F 'Do not fork a sequence'
243
+ ```
244
+ A quote that is not there is invented - discard the answer, not just the
245
+ quote. Ask once more; if it invents again, ask another model (step 4).
246
+ 2. **Find every copy.** The blocker often exists twice - once in a house rule,
247
+ once in a skill with a softer tail. Grep the whole request for a distinctive
248
+ phrase of it, then grep the project's `agents/` tree for the file to edit.
249
+ 3. **Check it is the project's file.** `fork-instructions.md`,
250
+ `memory-instructions.md`, `tools-instructions.md` are zen's own copies; load
251
+ **zen-instructions** before changing where that rule lives.
252
+ 4. **Second opinion when the self-report is thin.** The model that made the
253
+ call rationalises; another model reading the same replay often names the
254
+ conflict more plainly: `--model <ref>`. Ask the identical question: the same
255
+ question file.
256
+ 5. **Reproduce.** After the edit, rerun the case and check the graph: the
257
+ `tools` header row shows `fork x1` or `memory_search x1` where it did not
258
+ before. The answer predicted a fix; the graph confirms it.
259
+
260
+ ## 6. Reading the answer
261
+
262
+ | Answer says | Means | Fix |
263
+ | ---------------------------------------------------------- | ------------------------------------------- | ----------------------------------------------------------------- |
264
+ | `should-have-applied: none found` | nothing asked for it | add a mechanical rule at the point of decision |
265
+ | `steered-by: no instruction — my own default` | the model's habit filled a gap | add a mechanical rule at the point of decision |
266
+ | a rule quoted as `should-have-applied`, nothing against it | the rule is there but not reachable in time | move it earlier, or into the skill loaded for that task |
267
+ | a `steered-by` quote that argues against the better action | an instruction argued against it | narrow or remove the blocker, do not add a counter-rule beside it |
268
+ | `conflict:` names two rules | two instructions disagree | delete one; two copies of a rule is how drift starts |
269
+ | an exception is quoted as applying | a self-judged escape hatch | remove the hatch or make its condition checkable |
270
+ | no citation at all, general reasoning only | the question was too open, or led | rewrite with the three parts; do not act on it |
@@ -1,6 +1,6 @@
1
1
  ---
2
2
  name: zen-memory
3
- description: How agent memory is organised and how to configure it in `agents.yaml` - the `memory:` block, per-agent `access`/`sees`/`writes`/`autoRecall`, the four `memory_*` tools, kinds and relations, how recall ranks and stitches a subgraph, and how to design a memory strategy for a project. Includes the default usage rules every memory-enabled project must carry in `agents/memory-instructions.md` (references/memory-instructions.md), the script that says whether that copy is still current (scripts/check-instructions.sh), where a project's own customisations go instead (`agents/memory-policy-instructions.md`, under `requires: [memory]`), what to commit and what never to, how to keep a working file under `/memory` and re-run it later, and how to put memory in front of a `zen rag schema` or `zen rag docs` index so a search that already succeeded once is not paid for again.
3
+ description: How agent memory is organised and how to configure it in `agents.yaml` - the `memory:` block, per-agent `access`/`sees`/`writes`/`autoRecall`, the five `memory_*` tools, kinds and relations, how recall ranks and stitches a subgraph, when an agent should reach for `memory_grep` instead of `memory_search`, how to inspect a graph with `zen memory search`/`grep`/`export`, and how to design a memory strategy for a project. Includes the default usage rules every memory-enabled project must carry in `agents/memory-instructions.md` (references/memory-instructions.md), the script that says whether that copy is still current (scripts/check-instructions.sh), where a project's own customisations go instead (`agents/memory-policy-instructions.md`, under `requires: [memory]`), what to commit and what never to, how to keep a working file under `/memory` and re-run it later, and how to put memory in front of a `zen rag schema` or `zen rag docs` index so a search that already succeeded once is not paid for again.
4
4
  ---
5
5
 
6
6
  # Memory
@@ -79,30 +79,31 @@ agents:
79
79
  autoRecall: { limit: 3 }
80
80
  ```
81
81
 
82
- | Field | Type | Default | Meaning |
83
- | ------------ | -------------------------- | --------------- | -------------------------------------------- |
84
- | `access` | `read`/`read-write`/`full` | `read-write` | Which of the four tools this agent gets |
85
- | `sees` | name[] | `[]` | Private slices it may read, on top of `*` |
86
- | `writes` | name[] | `[*]` | Labels it may commit under |
87
- | `autoRecall` | boolean or `{ limit }` | `true`, limit 5 | Recall before a turn that follows user input |
82
+ | Field | Type | Default | Meaning |
83
+ | ------------ | -------------------------- | ---------------- | -------------------------------------------- |
84
+ | `access` | `read`/`read-write`/`full` | `read-write` | Which of the five tools this agent gets |
85
+ | `sees` | name[] | `[]` | Private slices it may read, on top of `*` |
86
+ | `writes` | name[] | `[*]` | Labels it may commit under |
87
+ | `autoRecall` | boolean or `{ limit }` | `true`, limit 10 | Recall before a turn that follows user input |
88
88
 
89
89
  `memory: true` is shorthand for all four defaults.
90
90
 
91
- ## The four tools
91
+ ## The five tools
92
92
 
93
93
  They are **not** listed in an agent's `tools:`. They are derived from the
94
94
  binding and appear when it exists, so `access` is the only thing that decides
95
95
  which of them the model is offered:
96
96
 
97
- | Level | Tools |
98
- | ------------ | ------------------------------- |
99
- | `read` | `memory_search`, `memory_load` |
100
- | `read-write` | the above, plus `memory_commit` |
101
- | `full` | the above, plus `memory_forget` |
97
+ | Level | Tools |
98
+ | ------------ | --------------------------------------------- |
99
+ | `read` | `memory_search`, `memory_grep`, `memory_load` |
100
+ | `read-write` | the above, plus `memory_commit` |
101
+ | `full` | the above, plus `memory_forget` |
102
102
 
103
103
  | Tool | Does |
104
104
  | --------------- | -------------------------------------------------------------------------- |
105
105
  | `memory_search` | Ranks, then stitches. Returns an outline of a subgraph and a legend of ids |
106
+ | `memory_grep` | Exact and complete. Every node containing a string, with the lines |
106
107
  | `memory_load` | Reads whole nodes by id. **The only call that counts as use** |
107
108
  | `memory_commit` | Writes a subgraph - nodes and the edges between them - in one transaction |
108
109
  | `memory_forget` | Removes nodes, their vectors and their file bytes together |
@@ -112,6 +113,29 @@ asked for; counting that as use would poison recency ranking. Commit is one
112
113
  call because a remembered thing is a subgraph, and building it with three calls
113
114
  leaves the graph half-formed when the model stops early.
114
115
 
116
+ Grep is separate from search because exactness is not a tuning of nearness. A
117
+ ranking returns the top of a list, so "nothing came back" and "nothing is there"
118
+ are the same result - and the second is what you need when the question is
119
+ whether a host, a flag or a command was already written down. Grep reads the
120
+ text, the metadata and the bytes of remembered files, applies the mask, leaves
121
+ out superseded nodes unless asked, and names any file it could not read. It is
122
+ also what an agent is supposed to reach for instead of running a shell `grep`
123
+ over `/memory`, which the house rules forbid.
124
+
125
+ It is not a diagnostic instrument, though - it is ordinary retrieval, and an
126
+ agent is expected to reach for it mid-run as readily as for search. The line
127
+ between them is what is being looked for: **a subject goes to `memory_search`,
128
+ a string goes to `memory_grep`** - a name, path, id, host, flag or command
129
+ spelled exactly, everywhere a thing is mentioned before it is changed, or
130
+ whether it was ever recorded at all. `agents/memory-instructions.md` puts that
131
+ division in front of the agent as a table, at the point where it chooses.
132
+
133
+ It takes `pattern` plus `in` (`text`, `metadata`, `file` - all three by
134
+ default), `regex`, `case_sensitive`, `kinds`, `include_superseded` and `limit`
135
+ (20 nodes). **`in: ["file"]` is the one worth knowing about**: only a node's
136
+ `text` is embedded, so the contents of a remembered script or config are
137
+ unreachable by any ranking, and grep is the only tool that reads them at all.
138
+
115
139
  `agents/memory-instructions.md` already explains all of this to the agent - how
116
140
  to read a recollection, when committing is worthwhile, why correction is a new
117
141
  node. It is house rules under `requires: [memory]`, so it reaches exactly the
@@ -180,7 +204,7 @@ that kind to build the system prompt.
180
204
  `SUPERSEDES`), then `INFORMED` context. A tight budget therefore degrades by
181
205
  dropping background rather than by truncating the answer.
182
206
 
183
- Defaults: 5 seeds, 2 hops, 25 nodes. `memory_search` takes `limit`, `max_hops`,
207
+ Defaults: 10 seeds, 2 hops, 25 nodes. `memory_search` takes `limit`, `max_hops`,
184
208
  `max_nodes`, `kinds` and `newer_than` to move them.
185
209
 
186
210
  What comes back is a `<memory-recollection>` block: an indented outline where
@@ -610,32 +634,52 @@ can act on.
610
634
  ## Inspecting and repairing it
611
635
 
612
636
  ```
613
- zen memory [stats|ls|show|export|merge|forget] [args] [options]
637
+ zen memory [stats|ls|search|grep|show|export|merge|forget] [args] [options]
614
638
  ```
615
639
 
616
640
  `zen memory export --open` is the one to reach for: one self-contained HTML
617
641
  page with every node, the graph as a diagram, and the remembered file's actual
618
642
  content in the detail pane. It reads **unmasked** - when the mask is what is
619
- wrong, the hidden part is exactly the part you need - and it contacts no model,
620
- so inspection is free and offline.
621
-
622
- | Question | Command |
623
- | ---------------------------------------- | -------------------------------- |
624
- | Is memory even on, and is it embedded? | `zen memory stats` |
625
- | What has this project learned? | `zen memory export --open` |
626
- | What is in one private slice? | `zen memory ls --audience audit` |
627
- | What has been corrected? | `zen memory ls --stale` |
628
- | What files are being kept? | `zen memory ls --files` |
629
- | Why was that recalled? | `zen memory show <id>` |
630
- | Fold parallel warmup graphs into one | `zen memory merge <dir...>` |
631
- | That should never have been written down | `zen memory forget <id>` |
643
+ wrong, the hidden part is exactly the part you need - and like everything here
644
+ bar `search`, it contacts no model, so inspection is free and offline.
645
+
646
+ `zen memory search <query>` is recall itself, run from a terminal: the same
647
+ ranker, the same walk, the same block a model would have been given, scores and
648
+ all. It is the only one that embeds, and the only one that can distinguish a
649
+ memory that is missing from a memory that is merely ranked sixth.
650
+
651
+ | Question | Command |
652
+ | ---------------------------------------- | ------------------------------------- |
653
+ | Is memory even on, and is it embedded? | `zen memory stats` |
654
+ | What has this project learned? | `zen memory export --open` |
655
+ | Is this host/flag/path in there at all? | `zen memory grep <pattern>` |
656
+ | Everywhere a thing is mentioned | `zen memory grep <pattern> --all` |
657
+ | What would an agent recall for this? | `zen memory search <query>` |
658
+ | Why did it _not_ recall that? | `zen memory search <q> --audience a` |
659
+ | What is in one private slice? | `zen memory ls --audience audit` |
660
+ | What has been corrected? | `zen memory ls --stale` |
661
+ | What files are being kept? | `zen memory ls --files` |
662
+ | One node in full, with what it links to | `zen memory show <id>` |
663
+ | What did a run add to its copy, or read? | `zen memory diff <base> --dir <copy>` |
664
+ | Fold parallel warmup graphs into one | `zen memory merge <dir...>` |
665
+ | That should never have been written down | `zen memory forget <id>` |
666
+
667
+ Never read a memory's `graph.json` or `manifest.json` with code: every question
668
+ above has a command, and `--json` on any of them is the stable shape.
632
669
 
633
670
  The directory is not fixed. `zen run --memory <dir>` sends one run's memory
634
671
  somewhere else - a scratch graph for a trial, one per branch, or a shared one
635
672
  outside the repository - and `zen memory --dir <dir>` reads any such directory
636
673
  with no project around it. Together they are also how you read a graph while a
637
674
  run holds its `.lock`: copy the directory, delete the copy's `.lock`, and point
638
- `--dir` at the copy.
675
+ `--dir` at the copy. `grep` needs none of that - it declines the lock, so it
676
+ reads a memory a run is writing, and the read-only `/memory` mount as well.
677
+
678
+ `zen run batch` is where parallel graphs usually come from now. Each item gets
679
+ its own copy to write into and the summary prints the `merge` line; a batch
680
+ that is only asking says `--memory-read-only` instead, and then every item
681
+ recalls from the one graph, because nothing writes and so nothing needs the
682
+ lock.
639
683
 
640
684
  `zen inspect` answers the other half: a run report shows the recollection block
641
685
  exactly as the model received it, which is how you tell "memory had nothing"
@@ -692,6 +736,9 @@ agents:
692
736
  - [ ] `autoRecall: false` on any agent whose user message is a payload.
693
737
  - [ ] Nothing authoritative is expected to live here - that is a skill's job.
694
738
  - [ ] The project's index skill says to verify a recalled route.
739
+ - [ ] `zen memory search` on a question the project actually gets back returns
740
+ what you expected, and says `ranked by meaning` rather than falling back to
741
+ term overlap.
695
742
  - [ ] `zen memory export --open` after a week of use, to see what it actually
696
743
  learned rather than what you hoped.
697
744
 
@@ -702,6 +749,8 @@ agents:
702
749
  | The `memory_*` tools are missing | No `memory:` on the agent. They come from the binding, never from `tools:` |
703
750
  | `zen memory` says the project has none | Neither a `memory:` block nor an agent binding - nothing is opened and no directory is made |
704
751
  | Recall finds a memory only when reworded | No embedder. `zen memory stats` says `embedding none` |
752
+ | A memory is in the graph but never comes back | Ask `zen memory search` for it: a score under `0.15` is dropped as noise, and `--audience <label>` shows whether a mask hid it |
753
+ | `zen memory search` says `ranked by term overlap` | It could not build the project's embedder - no credential, or the graph holds no vectors. That order is not the one a run gets |
705
754
  | Recall finds nothing after changing the embedder | Refused rather than mixed - a manifest records the model. Change it back, or start a new memory |
706
755
  | Vectors fewer than nodes | Some nodes were committed with no embedder; they are only reachable by term overlap |
707
756
  | The graph fills with restated requests | The commit rule is not in a prompt or skill. State the "would a later run redo this" test |