@zenera/cli 1.1.16 → 1.1.18

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 (71) hide show
  1. package/README.md +110 -19
  2. package/dist/banner.d.ts +19 -0
  3. package/dist/banner.js +12 -9
  4. package/dist/catalog.js +19 -20
  5. package/dist/command.d.ts +3 -0
  6. package/dist/commands/check.js +5 -1
  7. package/dist/commands/index.js +4 -1
  8. package/dist/commands/init.js +42 -7
  9. package/dist/commands/inspect.js +77 -13
  10. package/dist/commands/key.js +49 -1
  11. package/dist/commands/memory.js +16 -3
  12. package/dist/commands/meta.d.ts +3 -0
  13. package/dist/commands/meta.js +596 -0
  14. package/dist/commands/run.js +64 -35
  15. package/dist/engine.d.ts +15 -0
  16. package/dist/engine.js +26 -1
  17. package/dist/env.d.ts +20 -0
  18. package/dist/env.js +65 -0
  19. package/dist/home.d.ts +2 -0
  20. package/dist/home.js +2 -0
  21. package/dist/keys.d.ts +2 -0
  22. package/dist/keys.js +2 -0
  23. package/dist/main.js +1 -1
  24. package/dist/meta.d.ts +221 -0
  25. package/dist/meta.js +695 -0
  26. package/dist/podman.js +64 -2
  27. package/dist/projects.d.ts +9 -1
  28. package/dist/projects.js +19 -2
  29. package/dist/resolve.js +7 -1
  30. package/dist/sandbox.d.ts +11 -0
  31. package/dist/sandbox.js +24 -4
  32. package/dist/scaffold.d.ts +6 -0
  33. package/dist/scaffold.js +56 -15
  34. package/dist/session.d.ts +10 -0
  35. package/dist/session.js +19 -1
  36. package/dist/term.d.ts +7 -0
  37. package/dist/term.js +8 -1
  38. package/dist/tui/app.js +33 -5
  39. package/dist/tui/wrap.d.ts +1 -1
  40. package/dist/tui/wrap.js +1 -1
  41. package/dist/validate.js +57 -15
  42. package/package.json +3 -2
  43. package/templates/editor/.github/copilot-instructions.md +313 -94
  44. package/templates/editor/.github/prompts/project-review.prompt.md +74 -0
  45. package/templates/editor/.github/prompts/spec-apply-feedback.prompt.md +142 -0
  46. package/templates/editor/.github/prompts/spec-sync-project.prompt.md +392 -0
  47. package/templates/editor/.github/skills/zen-cli/references/check.md +6 -3
  48. package/templates/editor/.github/skills/zen-cli/references/frame.md +5 -3
  49. package/templates/editor/.github/skills/zen-cli/references/inspect.md +4 -3
  50. package/templates/editor/.github/skills/zen-cli/references/memory.md +14 -0
  51. package/templates/editor/.github/skills/zen-cli/references/projects.md +19 -2
  52. package/templates/editor/.github/skills/zen-cli/references/run.md +75 -16
  53. package/templates/editor/.github/skills/zen-cli/references/sandbox.md +6 -0
  54. package/templates/editor/.github/skills/zen-memory/SKILL.md +153 -33
  55. package/templates/editor/.github/skills/zen-memory/scripts/check-instructions.sh +115 -0
  56. package/templates/editor/.github/skills/zen-review/SKILL.md +123 -0
  57. package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +119 -0
  58. package/templates/editor/.github/skills/zen-review/scripts/review.sh +104 -0
  59. package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +197 -0
  60. package/templates/editor/.github/skills/zen-spec-sync/scripts/snapshot.sh +200 -0
  61. package/templates/editor/.vscode/settings.json +44 -4
  62. package/templates/parts/memory-terms.yaml.tmpl +16 -0
  63. package/templates/parts/memory.yaml.tmpl +12 -0
  64. package/templates/project/SPECIFICATION.md.tmpl +32 -2
  65. package/templates/project/agents/memory-instructions.md +278 -0
  66. package/templates/project/agents.yaml.tmpl +12 -3
  67. package/templates/project/env +28 -0
  68. package/templates/project/gitignore +4 -4
  69. package/templates/editor/.github/prompts/review-project.prompt.md +0 -36
  70. package/templates/editor/.github/prompts/sync-with-spec.prompt.md +0 -205
  71. /package/templates/project/{INSTRUCTIONS.md → agents/instructions.md} +0 -0
@@ -7,9 +7,10 @@
7
7
  >
8
8
  > It describes the Zenera Neo runtime, not this particular project, and `zen`
9
9
  > rewrites the whole tree on `init` and `open` - so put this project's own
10
- > conventions in `INSTRUCTIONS.md`, where they will survive. The runtime's own
11
- > reference is `docs/agents-yaml.md`, `docs/projects.md` and `DESIGN.md` in the
12
- > @zenera/neo repository - where they disagree with this file, they win.
10
+ > conventions in `agents/instructions.md`, where they will survive. The
11
+ > runtime's own reference is `docs/agents-yaml.md`, `docs/projects.md` and
12
+ > `DESIGN.md` in the @zenera/neo repository - where they disagree with this
13
+ > file, they win.
13
14
 
14
15
  ---
15
16
 
@@ -34,13 +35,23 @@ programmed: what an agent knows, which model answers, and which of the tools
34
35
  6. Every change must still load: `agents.yaml` is validated strictly at load,
35
36
  and `zen check` says so before a model is ever called.
36
37
 
37
- ### 0.1 Copilot is the meta-agent: CLI and RAG
38
+ ### 0.1 Copilot is the meta-agent: load the skill for every capability in use
38
39
 
39
40
  Copilot is always the meta-agent that creates and changes target projects. Load
40
41
  the editor's `zen-cli` skill before deciding how a target project should run,
41
42
  be validated, or use command-line capabilities. It is the command contract; do
42
43
  not reconstruct `zen` arguments from memory or call `--help` to discover them.
43
44
 
45
+ **Every runtime capability a project turns on carries obligations that are not
46
+ visible in `agents.yaml` and that `zen check` does not report.** Before
47
+ reviewing or changing a project, list the capabilities it has turned on and load
48
+ the editor skill for each one - `zen-memory` for a `memory:` block, `zen-rag-
49
+ schema` or `zen-rag-docs` for an index, `zen-cli` always. A capability that is
50
+ already configured and already passing `zen check` is exactly the case that
51
+ looks finished and is not: the obligation lives in the skill, so a review that
52
+ never opens the skill cannot find what is missing. This applies whatever
53
+ prompted the change - a task scoped to `SPECIFICATION.md` does not narrow it.
54
+
44
55
  First determine whether the target project uses RAG: a `zen rag` command in an
45
56
  agent prompt or skill, RAG tools supplied by its host, or a documentation or
46
57
  schema index it is expected to consult all count. When it does, also load the
@@ -48,8 +59,9 @@ schema index it is expected to consult all count. When it does, also load the
48
59
 
49
60
  Then create or maintain `agents/skills/rag_search/SKILL.md` in the target
50
61
  project. Its description must say when an agent should load it. Its body must
51
- name the target's actual RAG surface and index location, state which agents may
52
- use it, and give an executable retrieval procedure:
62
+ name the target's actual RAG surface and index location, open by stating what an
63
+ agent needs to follow it and what to do without that, and give an executable
64
+ retrieval procedure:
53
65
 
54
66
  1. Discover document and section names with the exact listing command or tool.
55
67
  2. Start with hybrid search for a complete natural-language question.
@@ -61,6 +73,16 @@ use it, and give an executable retrieval procedure:
61
73
  5. Retrieve a complete section verbatim, or list a table and read its inclusive
62
74
  line range when every row is needed.
63
75
 
76
+ **State the prerequisite, not the audience.** `skills.allow` restricts loading
77
+ and `zen check` validates it; a list of agent names in the body is a second copy
78
+ of that binding with nothing keeping the two in step, and it is stale the first
79
+ time an agent is renamed (§4.2, rule 10). What a reader can act on is what the
80
+ procedure needs - the RAG tools, or `sandbox:*` and the index at its path - and
81
+ what to do without them: _"say so and stop; do not answer from memory"_ (§4.2,
82
+ rule 6). Put it in the first lines of the body, because the catalog is mounted
83
+ whole at `/skills` before any binding applies (§3.4.1), so an agent that was
84
+ never granted this skill can still read the file and start following it.
85
+
64
86
  Keep this as runtime guidance, not a pointer to this editor reference: a target
65
87
  agent cannot read `.github/` or this project layout while it runs. Include only
66
88
  the commands, tools, paths, and corpus-specific constraints that exist in the
@@ -68,6 +90,42 @@ target project. Grant the agents that need CLI RAG the necessary `sandbox:*`
68
90
  tool access; give tool-based RAG users the configured RAG tools instead. Run
69
91
  `zen check` after adding or changing the skill.
70
92
 
93
+ Memory has one such obligation and it is absolute: **a project with a `memory:`
94
+ block carries the `zen-memory` skill's `references/memory-instructions.md` in its
95
+ own `agents/memory-instructions.md`.** `zen init` writes both, since it scaffolds
96
+ memory on; what needs watching is a project that deleted the file, or one whose
97
+ copy has fallen behind the reference. Do not read the two files against each
98
+ other - they drift by trailing whitespace inside tables, which is invisible.
99
+ The skill ships the check:
100
+
101
+ ```sh
102
+ .github/skills/zen-memory/scripts/check-instructions.sh # the verdict
103
+ .github/skills/zen-memory/scripts/check-instructions.sh fix # copy the reference over
104
+ ```
105
+
106
+ It is a copy, never a transcription - the reference ships inside the project,
107
+ because `zen init` and `zen open` write this whole `.github/` tree, so `fix` is
108
+ just `cp` from one to the other.
109
+
110
+ Nothing else tells a running agent how the store works, so without it nothing
111
+ forbids an agent from pointing `grep` or `cat` at `/memory` - a read that
112
+ bypasses the audience mask and serves superseded nodes as current. Keep the copy
113
+ byte-identical and put this project's own memory policy in a second topic file,
114
+ `agents/memory-policy-instructions.md`, which is read straight after it: then the
115
+ copy can be re-run after any `zen init` or `zen open` refreshes the reference,
116
+ without losing anything. Never paraphrase the reference into prose of your own.
117
+ See §5.3.
118
+
119
+ A project with a `SPECIFICATION.md` carries one more: **`.spec-sync/` records
120
+ what the last `/spec-sync-project` pass applied**, and the `zen-spec-sync` skill is
121
+ loaded before running that prompt, whether or not a baseline exists yet. The
122
+ state is committed, because a record only the last machine has is not a record.
123
+ Two things to watch for, neither of which `zen check` reports: a baseline that
124
+ moved without a history entry to match it, which is a pass claiming work it did
125
+ not do, and a `.spec-sync/baseline/` whose `manifest.txt` no longer matches its
126
+ files. Both are reported, not quietly repaired - rewriting the manifest asserts
127
+ a pass that never happened.
128
+
71
129
  ---
72
130
 
73
131
  ## 1. Mental model
@@ -76,12 +134,12 @@ tool access; give tool-based RAG users the configured RAG tools instead. Run
76
134
 
77
135
  An agent is four things and nothing more:
78
136
 
79
- | Part | Where it lives | What it decides |
80
- | --------------- | ---------------------------------------------- | ----------------------------- |
81
- | **Instruction** | `INSTRUCTIONS.md` + `agents/prompts/<name>.md` | How it behaves |
82
- | **Model** | `agents.yaml` → `model:` | How well and how expensively |
83
- | **Tools** | `agents.yaml` → `tools:` | What it can _do_ |
84
- | **Knowledge** | `agents/skills/*` + memory | What it can _know_, on demand |
137
+ | Part | Where it lives | What it decides |
138
+ | --------------- | ------------------------------------------------------ | ----------------------------- |
139
+ | **Instruction** | `agents/*instructions.md` + `agents/prompts/<name>.md` | How it behaves |
140
+ | **Model** | `agents.yaml` → `model:` | How well and how expensively |
141
+ | **Tools** | `agents.yaml` → `tools:` | What it can _do_ |
142
+ | **Knowledge** | `agents/skills/*` + memory | What it can _know_, on demand |
85
143
 
86
144
  Plus two relations: **handoffs** - which other agents it may transfer control to
87
145
 
@@ -116,7 +174,7 @@ is deciding **what is in that sequence and in what order**.
116
174
  ```
117
175
  ┌─────────────────────────────────────────────┐
118
176
  │ tool schemas fixed at load │ ← stable, cacheable
119
- │ INSTRUCTIONS.md shared by all agents │ ← stable, cacheable
177
+ │ agents/*instructions shared by all agents │ ← stable, cacheable
120
178
  │ agent prompt this agent's brief │ ← stable per agent
121
179
  │ skill index names + descriptions │ ← stable per agent
122
180
  │ preloaded skills activated turn 0 │ ← stable, in the cached prefix
@@ -159,10 +217,12 @@ my-project/
159
217
  │ ├── copilot-instructions.md this file
160
218
  │ ├── prompts/*.prompt.md tasks you invoke by name
161
219
  │ └── skills/*/SKILL.md reference the editor loads on demand
162
- ├── .env credentials - NEVER committed
163
- ├── INSTRUCTIONS.md house rules, prepended to every agent
220
+ ├── .env this project's environment - NEVER committed
221
+ ├── .spec-sync/ what the last /spec-sync-project applied - §0.1
164
222
  ├── agents.yaml who exists, what they may reach for
165
223
  ├── agents/
224
+ │ ├── instructions.md house rules, prepended to every agent
225
+ │ ├── memory-instructions.md more of them - any `<topic>-instructions.md`
166
226
  │ ├── prompts/
167
227
  │ │ ├── intake.md one agent's own brief
168
228
  │ │ └── adjuster.md
@@ -185,13 +245,18 @@ Only `agents.yaml` is required, and only `agents:` is required inside it.
185
245
  The config is found by name, in order: `agents.yaml`, `agents.yml`,
186
246
  `agents/agents.yaml`, `agents/agents.yml`.
187
247
 
248
+ The house rules are `agents/instructions.md` plus every
249
+ `agents/<topic>-instructions.md`, read in filename order and prepended to every
250
+ agent (§3.2). A project written before the move keeps its `INSTRUCTIONS.md` in
251
+ the root; that still loads, and `zen check` says to move it.
252
+
188
253
  ### 2.2 Variants
189
254
 
190
255
  **Single agent, knowledge-heavy** - the most under-used shape. One agent, one
191
256
  prompt, a large skill catalog. Prefer this until routing is genuinely needed.
192
257
 
193
258
  ```
194
- INSTRUCTIONS.md · agents.yaml · agents/prompts/assistant.md · agents/skills/** (20 skills)
259
+ agents.yaml · agents/instructions.md · agents/prompts/assistant.md · agents/skills/** (20 skills)
195
260
  ```
196
261
 
197
262
  **Router + specialists** - a cheap intake agent that classifies and hands off.
@@ -236,10 +301,10 @@ dots.
236
301
  There are two sets of instructions in this repository and they are not for the
237
302
  same reader. Keeping them apart is the single easiest thing to get wrong.
238
303
 
239
- | Tree | Read by | About |
240
- | ---------------------------- | ------------------------------------------ | ----------------------------------- |
241
- | `INSTRUCTIONS.md`, `agents/` | the **project's** agents, at run time | the domain this system works in |
242
- | `.github/` | the **editor's** assistant, while you edit | how a project of this kind is built |
304
+ | Tree | Read by | About |
305
+ | ------------------------ | ------------------------------------------ | ----------------------------------- |
306
+ | `agents.yaml`, `agents/` | the **project's** agents, at run time | the domain this system works in |
307
+ | `.github/` | the **editor's** assistant, while you edit | how a project of this kind is built |
243
308
 
244
309
  The `.github/` tree follows the same progressive-disclosure discipline the
245
310
  agents do, for the same reason - it is a prefix somebody pays for:
@@ -258,7 +323,8 @@ agents do, for the same reason - it is a prefix somebody pays for:
258
323
 
259
324
  `zen init` and `zen open` rewrite this whole tree from the version of `zen` in
260
325
  hand, so **edits inside `.github/` do not survive**. Project-specific conventions
261
- belong in `INSTRUCTIONS.md` and the agent prompts, which are never overwritten.
326
+ belong in `agents/instructions.md` and the agent prompts, which are never
327
+ overwritten.
262
328
 
263
329
  ### 2.5 What a running agent can actually see
264
330
 
@@ -276,10 +342,10 @@ Commands run inside the container `sandbox:` describes (§3.7): the same
276
342
  `/workspace`, and whatever the image ships.
277
343
 
278
344
  Everything else in the project directory is **invisible at run time** -
279
- `agents.yaml`, `INSTRUCTIONS.md`, `agents/prompts/`, `agents/skills/` under that
280
- name, `sandbox/Dockerfile`, `.env`, `.github/`, `sessions/`, and the project
281
- root itself. `zen` reads them to build the run; they are never a path an agent
282
- can open.
345
+ `agents.yaml`, `agents/instructions.md`, `agents/prompts/`, `agents/skills/`
346
+ under that name, `sandbox/Dockerfile`, `.env`, `.github/`, `sessions/`, and the
347
+ project root itself. `zen` reads them to build the run; they are never a path an
348
+ agent can open.
283
349
 
284
350
  Two consequences:
285
351
 
@@ -298,13 +364,13 @@ prose**, in the prompt - never sent to read the file that configured it.
298
364
 
299
365
  #### Checklist - no path an agent cannot open
300
366
 
301
- Run this over `INSTRUCTIONS.md`, every `agents/prompts/*.md` and every
302
- `agents/skills/*/SKILL.md` after editing any of them. Every path-shaped token in
303
- those files is read by a model as an instruction to open something:
367
+ Run this over every `agents/*instructions.md`, every `agents/prompts/*.md` and
368
+ every `agents/skills/*/SKILL.md` after editing any of them. Every path-shaped
369
+ token in those files is read by a model as an instruction to open something:
304
370
 
305
371
  - [ ] Every absolute path begins `/workspace`, `/assets`, `/skills` or
306
372
  `/memory`. Nothing else exists.
307
- - [ ] No project file is named: `agents.yaml`, `INSTRUCTIONS.md`,
373
+ - [ ] No project file is named: `agents.yaml`, `agents/instructions.md`,
308
374
  `agents/prompts/…`, `agents/skills/…`, `sandbox/Dockerfile`, `.env`,
309
375
  `.github/…`, `sessions/…`, `SPECIFICATION.md`, `README.md`, `docs/…`.
310
376
  - [ ] Nothing escapes a mount: no `../`, no `~`, no host path (`/Users/…`,
@@ -327,13 +393,17 @@ Finding the candidates, from the project root - every path-shaped token in the
327
393
  three trees, minus the ones under a mount:
328
394
 
329
395
  ```sh
330
- grep -Eohr '[~.]?/?[A-Za-z0-9_.-]*/[A-Za-z0-9_.*-]+' \
331
- INSTRUCTIONS.md agents/prompts agents/skills \
332
- | sort -u | grep -Ev '^/(workspace|assets|skills|memory)(/|$)'
396
+ .github/skills/zen-review/scripts/check-paths.sh
333
397
  ```
334
398
 
335
- Everything it prints is either a false positive (a url, a `path/to` in a
336
- sentence, `and/or`) or a path the agent cannot open. There is no third case.
399
+ It prints each candidate with the file and line it is on, and exits non-zero
400
+ while any remain. Everything it prints is either a path the agent cannot open or
401
+ noise the script has not learned yet - a url, a `path/to` in a sentence, an
402
+ `and/or` - and there is no third case. It strips the noise it does know about,
403
+ so a candidate that survives is one to explain or fix rather than one to skim
404
+ past. `check-paths.sh raw` is the sweep with nothing filtered, for when the
405
+ filter itself is the suspect. The `zen-review` skill says what it covers and
406
+ what it cannot.
337
407
 
338
408
  ---
339
409
 
@@ -410,7 +480,7 @@ provider with a missing key does not fail loading.
410
480
  - `agents[].handoffs` naming an unknown agent, or the agent itself
411
481
  - `agents[].skills.provider` / `.allow` / `.preload` naming something absent
412
482
  - a `preload:` entry missing from `allow:`
413
- - `agents[].fork.agents` naming an unknown agent, or being empty; `maxBranches` below 2
483
+ - `agents[].fork.agents` naming an unknown agent, or being empty; `maxBranches` below 1
414
484
  - `system:` pointing at a missing file, or outside the project root
415
485
 
416
486
  **Not caught at load** - a model id whose prefix is missing and so resolves to the
@@ -499,14 +569,26 @@ hide that. `maxBatch` therefore defaults to `1`; raise it only for a
499
569
  `zen check` reports every declared embedding beside the models, with the
500
570
  credential each one would need.
501
571
 
502
- ### 3.2 `INSTRUCTIONS.md`
572
+ ### 3.2 `agents/instructions.md` and friends
503
573
 
504
- House rules, read **once** and prepended to every agent's system prompt. It is
505
- the stable head of the cached prefix, so it should change rarely. The name is
574
+ House rules, read **once** and prepended to every agent's system prompt. They are
575
+ the stable head of the cached prefix, so they should change rarely. The name is
506
576
  deliberately not `AGENTS.md` - that one belongs to the coding assistant reading
507
577
  this file, and these rules address the project's own agents.
508
578
 
509
- Put here only what is true for **every** agent:
579
+ There may be more than one. `agents/instructions.md` is the base; every
580
+ `agents/<topic>-instructions.md` is read after it, in filename order, and every
581
+ agent gets all of them. Each arrives as its own block tagged with the file it
582
+ came from - `<house_rules src="agents/memory-instructions.md">` - so the model
583
+ can tell one document from the next.
584
+
585
+ Split a topic out when it is true for every agent but belongs to **one
586
+ capability**: the memory usage rules (§5.3) are the standard case - they arrive
587
+ when `memory:` is turned on and are deleted when it is turned off, which is a
588
+ whole file rather than a section somebody has to find. Do not split by author,
589
+ by date, or to keep a file short; that is what a skill is for.
590
+
591
+ Put in them only what is true for **every** agent:
510
592
 
511
593
  - identity and domain ("You work the property claims desk")
512
594
  - non-negotiable prohibitions (regulatory, legal, safety)
@@ -533,13 +615,13 @@ follow. So:
533
615
  - Anything only one agent needs goes in that agent's prompt instead. If you find
534
616
  yourself writing "if you are the router…", you are in the wrong file.
535
617
 
536
- Target 20–60 lines. If it exceeds ~100, split the stable half out into a
618
+ Target 20–60 lines each. If one exceeds ~100, split the stable half out into a
537
619
  preloaded skill.
538
620
 
539
621
  ### 3.3 `agents/prompts/<name>.md`
540
622
 
541
623
  Plain Markdown, no frontmatter. This is the agent's _job description_, appended
542
- after `INSTRUCTIONS.md`.
624
+ after the house rules.
543
625
 
544
626
  Structure that works:
545
627
 
@@ -574,8 +656,8 @@ literally; it states the boundary ("you do not have them") with the _reason_; it
574
656
  forbids the specific failure that agent actually exhibits.
575
657
 
576
658
  Write it as a prompt, under the rules in §4.2 - **instructive and concise**. It
577
- tells one agent what to do; it never explains the system (`INSTRUCTIONS.md`
578
- already did, §3.2), never repeats a house rule, and never describes the runtime.
659
+ tells one agent what to do; it never explains the system (the house rules
660
+ already did, §3.2), never repeats one of them, and never describes the runtime.
579
661
  Every line should be an instruction the model can act on or a boundary it can
580
662
  check itself against.
581
663
 
@@ -696,10 +778,18 @@ groups - the workspace tools (§3.6), the sandbox tools (§3.7) and the web tool
696
778
  the machine, so `tools:` is the whole permission model: an agent that does not
697
779
  name a tool cannot use it, whatever its prompt says.
698
780
 
699
- Two rules follow:
781
+ Three rules follow:
700
782
 
701
783
  - **Grant the narrowest set the job needs.** An agent that only reviews should
702
784
  not be holding the tools that overwrite files.
785
+ - **Grant by group, then subtract.** Write `workspace:*` and take away what this
786
+ agent must not have - not a hand-picked list of names. The tools in a group are
787
+ designed to be used together, and a list assembled one name at a time leaves out
788
+ the companion the model reaches for next: `write_file` without `apply_patch`
789
+ turns every one-line edit into a whole-file rewrite, and `read_file` without
790
+ `list_dir` and `find_files` leaves it guessing at paths. A group also tracks the
791
+ runtime - a tool added to it later reaches the agent, where an enumerated list
792
+ silently stays behind.
703
793
  - **Say in the prompt when to reach for what.** A granted tool the prompt never
704
794
  mentions is used at the model's discretion, which is not the same as never.
705
795
 
@@ -759,6 +849,13 @@ refuses the file. `workspace:*` needs no quoting. There is no name globbing -
759
849
  `read_*` is an unknown tool, because a selector should track a declared set, not
760
850
  a naming habit.
761
851
 
852
+ Both agents above are written the way to write them: **the group, minus the
853
+ exceptions**. `tools: [read_file, write_file]` is the shape to avoid - it reads
854
+ as a considered decision and is usually an incomplete one, since the tool that
855
+ makes the granted one usable is the tool that was left out. Subtracting says
856
+ which capability is being withheld, which is the thing a reviewer needs to check
857
+ and the thing the next tool added to the group will not quietly defeat.
858
+
762
859
  `zen run --read-only` withholds the four mutating tools whatever `agents.yaml`
763
860
  asks for: the deployment overriding the repository, as everywhere else.
764
861
 
@@ -808,23 +905,34 @@ sandbox:
808
905
  env: [HTTPS_PROXY, NO_PROXY] # host variables to forward, by NAME
809
906
  ```
810
907
 
811
- | Field | Default | Meaning |
812
- | --------- | --------------------------------------------- | -------------------------------------------- |
813
- | `image` | `docker.io/library/python:3.14-slim-bookworm` | The base image commands run in |
814
- | `build` | none | A Dockerfile to build instead |
815
- | `cpus` | the host's | Fractional cores |
816
- | `memory` | the host's | MiB |
817
- | `network` | `bridge` | `bridge` / `none` / `host` |
818
- | `workdir` | `/workspace` | Mount point and default cwd |
819
- | `timeout` | `120` | Seconds per command |
820
- | `user` | the image's | uid, name, or `uid:gid` |
821
- | `persist` | `false` - **set it to `true`** | Keep the container between runs of a session |
822
- | `env` | none | Host variables to forward, **names** |
908
+ | Field | Default | Meaning |
909
+ | --------- | --------------------------------------------- | --------------------------------------------- |
910
+ | `image` | `docker.io/library/python:3.14-slim-bookworm` | The base image commands run in |
911
+ | `build` | none | A Dockerfile to build instead |
912
+ | `cpus` | the host's | Fractional cores |
913
+ | `memory` | the host's | MiB |
914
+ | `network` | `bridge` | `bridge` / `none` / `host` |
915
+ | `workdir` | `/workspace` | Mount point and default cwd |
916
+ | `timeout` | `120` | Seconds per command |
917
+ | `user` | the image's | uid, name, or `uid:gid` |
918
+ | `persist` | `false` - **set it to `true`** | Keep the container between runs of a session |
919
+ | `env` | none | Host variables to forward, **names** |
920
+ | `keys` | `true` | Whether model credentials reach the container |
823
921
 
824
922
  `env:` takes **names, never values** - a value here would be a secret in the
825
923
  repository - and anything credential-shaped (`KEY`, `TOKEN`, `SECRET`,
826
924
  `PASSWORD`, `CREDENTIAL`) is refused at load.
827
925
 
926
+ **Model credentials are already inside the container** (`keys:`, default
927
+ `true`). Every provider key the run holds is forwarded by name, and a Vertex
928
+ service-account file is bind-mounted read-only at `/run/zenera/keys` with
929
+ `GOOGLE_APPLICATION_CREDENTIALS` rewritten to point there - wherever it sits on
930
+ the host, keyring included. So a `zen` command that embeds (`zen rag … search`)
931
+ works in the sandbox: do not assume otherwise, do not route around it, and
932
+ never copy a key file into the project to "reach" the container. Only
933
+ `keys: false` / `zen run --no-keys` withholds them, and `network: none` is what
934
+ stops the call going out.
935
+
828
936
  **`build:`, when no published image fits.** A project that needs two runtimes,
829
937
  or a pinned toolchain, names a Dockerfile instead of an image - `zen init`
830
938
  writes one at `sandbox/Dockerfile` with Python and Node in it:
@@ -993,6 +1101,7 @@ zen run open the entry agent on this project
993
1101
  zen run "what changed?" one shot; stdout is the answer
994
1102
  zen run --session <id> continue a session
995
1103
  zen run --workspace ./repo what the agent may read and write
1104
+ zen run --memory ./mem where the agents remember into, instead of memory/
996
1105
  zen run --model careful override the default model for this run
997
1106
  zen run --image <ref> override the sandbox image for this run, ignoring build:
998
1107
  zen run --read-only withhold every tool that can write
@@ -1013,11 +1122,17 @@ OPENAI_API_KEY=...
1013
1122
  ANTHROPIC_API_KEY=...
1014
1123
  GOOGLE_APPLICATION_CREDENTIALS=./.keys/vertex.json
1015
1124
  EXA_API_KEY=...
1125
+ ZENERA_META_MODEL=vertex/gemini-3.8-flash
1016
1126
  ```
1017
1127
 
1018
1128
  Never commit. Never inline a key into `agents.yaml` - use `${VAR}`. Never print a
1019
1129
  key in a log line, a test fixture, or a chat message.
1020
1130
 
1131
+ `ZENERA_META_MODEL` is the exception that is not a credential: it names the model
1132
+ `zen meta` runs the meta agent on in this project, as a zen ref. It is here
1133
+ rather than in `agents.yaml` because it is a choice about a tool, not about the
1134
+ project's own agents. `zen meta model` prints where the answer came from.
1135
+
1021
1136
  ### 3.11 `assets/`
1022
1137
 
1023
1138
  `assets/` next to `agents.yaml` - or `assets: <path>` - is reference material
@@ -1041,13 +1156,14 @@ is a different project, not a different key.
1041
1156
  ### 4.1 Composition order
1042
1157
 
1043
1158
  ```
1044
- 1. INSTRUCTIONS.md (shared, once, all agents)
1045
- 2. agents/prompts/<n>.md (this agent)
1046
- 3. skill index (rendered by the runtime - do not hand-write it)
1047
- 4. preloaded skills (activated before the first call)
1159
+ 1. agents/instructions.md (shared, once, all agents)
1160
+ 2. agents/*-instructions.md (shared too, filename order)
1161
+ 3. agents/prompts/<n>.md (this agent)
1162
+ 4. skill index (rendered by the runtime - do not hand-write it)
1163
+ 5. preloaded skills (activated before the first call)
1048
1164
  ```
1049
1165
 
1050
- Never duplicate `INSTRUCTIONS.md` content into an agent prompt; never hand-render
1166
+ Never duplicate house-rules content into an agent prompt; never hand-render
1051
1167
  a list of skills into a prompt (the runtime does it, and a hand-written one goes
1052
1168
  stale silently).
1053
1169
 
@@ -1089,8 +1205,8 @@ When behaviour is wrong, in this order:
1089
1205
 
1090
1206
  1. **Read the actual assembled prompt**, not the file. Use the inspect report.
1091
1207
  2. Is the instruction _present_? (Missed skill load, wrong agent, compaction.)
1092
- 3. Is it _contradicted_ by `INSTRUCTIONS.md` or a skill? Adjacent contradictions
1093
- win over distant ones; later text usually wins over earlier.
1208
+ 3. Is it _contradicted_ by a house-rules file or a skill? Adjacent
1209
+ contradictions win over distant ones; later text usually wins over earlier.
1094
1210
  4. Is it _specific enough to be checkable_? Rewrite as a testable assertion.
1095
1211
  5. Only then consider a stronger model.
1096
1212
 
@@ -1105,15 +1221,15 @@ it forever.
1105
1221
 
1106
1222
  The decision for every piece of knowledge:
1107
1223
 
1108
- | Where | Cost | Use when |
1109
- | ------------------- | ----------------------- | ----------------------------------------------------- |
1110
- | `INSTRUCTIONS.md` | every call, every agent | true always, for everyone |
1111
- | agent prompt | every call, one agent | true always, for this job |
1112
- | **preloaded skill** | every call, one agent | always needed, but versioned/shared separately |
1113
- | **indexed skill** | one line until loaded | needed _sometimes_, model can tell when from one line |
1114
- | **searched skill** | nothing until searched | catalog too large to index (>~30 entries) |
1115
- | **tool** | schema only | needs live data, exact arithmetic, or a side effect |
1116
- | **memory** | recall block when hit | learned across runs, not authored |
1224
+ | Where | Cost | Use when |
1225
+ | ------------------------- | ----------------------- | ----------------------------------------------------- |
1226
+ | `agents/*instructions.md` | every call, every agent | true always, for everyone |
1227
+ | agent prompt | every call, one agent | true always, for this job |
1228
+ | **preloaded skill** | every call, one agent | always needed, but versioned/shared separately |
1229
+ | **indexed skill** | one line until loaded | needed _sometimes_, model can tell when from one line |
1230
+ | **searched skill** | nothing until searched | catalog too large to index (>~30 entries) |
1231
+ | **tool** | schema only | needs live data, exact arithmetic, or a side effect |
1232
+ | **memory** | recall block when hit | learned across runs, not authored |
1117
1233
 
1118
1234
  ### 5.2 Skill bindings
1119
1235
 
@@ -1166,6 +1282,39 @@ Every node carries an **audience**, and an agent's `sees` is the set it reads:
1166
1282
  one graph, masked per agent, never one graph each. The four `memory_*` tools are
1167
1283
  derived from `access` and are never listed in `tools:`.
1168
1284
 
1285
+ **Memory comes on.** `zen init` writes the block above, `memory: true` on the
1286
+ default agent, and the half nobody would guess was part of it:
1287
+ `agents/memory-instructions.md`, a copy of the `zen-memory` skill's
1288
+ `references/memory-instructions.md`, which the project already holds. Adding
1289
+ memory to a project that has none is both of those edits, and a copy that was
1290
+ lost or went stale is one command:
1291
+
1292
+ ```sh
1293
+ .github/skills/zen-memory/scripts/check-instructions.sh fix
1294
+ ```
1295
+
1296
+ It is what tells the agent that the store is reached only through the tools, that
1297
+ `memory_search` clips a node's text and `memory_load` reads it whole, that a
1298
+ remembered file's path comes from `memory_load` and not from listing `/memory`,
1299
+ what a node must carry to be worth having, and that a correction is a
1300
+ `SUPERSEDES` edge rather than an edit. It is its own file rather than a section of
1301
+ `agents/instructions.md` because it arrives with the `memory:` block and leaves
1302
+ with it.
1303
+
1304
+ **Leave that file as a pure copy.** Anything this project decides for itself -
1305
+ which audience holds what, what must never be written down, what an agent is
1306
+ expected to commit at the end of a job - goes in
1307
+ `agents/memory-policy-instructions.md`. Topic files are read in filename order,
1308
+ so the policy lands directly after the rules it qualifies, and the copy stays
1309
+ re-runnable: the reference is rewritten by every `zen init` and `zen open`, and
1310
+ keeping up with it is then the same one-line command rather than a hand-patch.
1311
+
1312
+ `zen check` validates the `memory:` block and says nothing about the rules'
1313
+ absence, so this is checked every time, by
1314
+ `.github/skills/zen-memory/scripts/check-instructions.sh` and never by reading
1315
+ the two files against each other: they drift by trailing whitespace inside a
1316
+ table, and the script is what can see that.
1317
+
1169
1318
  Do not treat memory as a database. It is for things learned that should
1170
1319
  persist. Anything authoritative - a rate, a policy clause, a procedure - belongs
1171
1320
  in a skill, where it is versioned and reviewable.
@@ -1179,12 +1328,12 @@ in front of a `zen rag` index - is in the `zen-memory` skill.
1179
1328
  Rules that follow directly from "stable prefix = cache hit":
1180
1329
 
1181
1330
  - Do not reorder `agents.yaml` for cosmetic reasons - tool order is prompt order.
1182
- - Do not put timestamps, run ids, or "today is …" in `INSTRUCTIONS.md` or a
1331
+ - Do not put timestamps, run ids, or "today is …" in a house-rules file or a
1183
1332
  prompt. A changing prefix is a permanent cache miss. Put volatile facts in a
1184
1333
  tool result.
1185
1334
  - Prefer `preload` over an instruction telling the model to load a skill first.
1186
1335
  - Keep the volatile half of an instruction in the agent prompt and the stable
1187
- half in `INSTRUCTIONS.md`, not the reverse.
1336
+ half in the house rules, not the reverse.
1188
1337
 
1189
1338
  ---
1190
1339
 
@@ -1269,7 +1418,8 @@ interchangeable:
1269
1418
  - The other agent should **own the conversation from here** → `handoffs:`, and
1270
1419
  something on the far side has to lead back.
1271
1420
  - This agent needs **an answer and then carries on** → `fork:`. Never a handoff:
1272
- a handoff spends the conversation to get the answer.
1421
+ a handoff spends the conversation to get the answer. One branch is enough -
1422
+ a fork of one is exactly "ask the specialist and continue".
1273
1423
 
1274
1424
  But the return is **condensed**: `A → fork → B` rejoins as one tool result
1275
1425
  holding B's answer, so A never sees the steps B took - no tool calls, no files
@@ -1297,7 +1447,7 @@ agents:
1297
1447
  | Field | Default | Meaning |
1298
1448
  | ------------- | -------------------- | ------------------------------------- |
1299
1449
  | `agents` | every declared agent | Which agents a branch may run |
1300
- | `maxBranches` | unlimited | Cap on branches per call; minimum `2` |
1450
+ | `maxBranches` | unlimited | Cap on branches per call; minimum `1` |
1301
1451
 
1302
1452
  The **model** decides the split: it names N branches, each with self-contained
1303
1453
  instructions. They run truly concurrently and rejoin as **one tool call and one
@@ -1310,8 +1460,10 @@ Rules worth knowing before you write the key:
1310
1460
  is not an error, and one role fanned out over ten items is the common shape.
1311
1461
  The list reaches the model as an `enum`, so a name outside it cannot even be
1312
1462
  decoded.
1313
- - A fork always needs **at least two** branches. A one-branch call is refused
1314
- with a message telling the model to do the work itself instead.
1463
+ - A fork of **one** branch is delegation, and it is valid: one assignment run
1464
+ elsewhere, its conclusion returned, its transcript left out of this
1465
+ conversation. Use it when another agent suits the job better, or when the job
1466
+ would fill the caller's context with material it has no use for afterwards.
1315
1467
  - **Branches cannot talk to each other.** If branch B needs branch A's answer,
1316
1468
  it is a sequence, not a fork - keep it in one conversation.
1317
1469
  - Nesting is capped by the run's `maxForkDepth` (2 by default), so a branch may
@@ -1330,10 +1482,12 @@ agent's prompt which one this work wants:
1330
1482
  - `none` - system prompt plus instructions only. Cheapest; for independent
1331
1483
  lookups.
1332
1484
 
1333
- Declaring `fork:` only makes the tool available. Say in the agent's prompt when
1334
- to reach for it, in the terms of this domain - _"When the request covers more
1335
- than one region, fork one branch per region and merge their findings"_ - or a
1336
- weaker model will work through the list serially and never call it.
1485
+ Declaring `fork:` only makes the tool available. What a fork costs and what
1486
+ survives the join is explained to the model by the runtime, in the system prompt
1487
+ of every agent holding the key. What is left to you is _when_, in the terms of
1488
+ this domain - _"When the request covers more than one region, fork one branch
1489
+ per region and merge their findings"_ - or a weaker model will work through the
1490
+ list serially and never call it.
1337
1491
 
1338
1492
  ### 6.5 Termination
1339
1493
 
@@ -1736,6 +1890,16 @@ ok, `1` failed, `2` usage, `3` invalid project, `4` no usable credential.
1736
1890
 
1737
1891
  ## 9. Review checklist
1738
1892
 
1893
+ Four of these are decidable, and are one command - `zen check`, the path sweep,
1894
+ the memory copy, the spec-sync record, in that order:
1895
+
1896
+ ```sh
1897
+ .github/skills/zen-review/scripts/review.sh
1898
+ ```
1899
+
1900
+ Run it first and read what it says. Everything else below is judgement, which is
1901
+ why it is still a list. The `zen-review` skill has the detail.
1902
+
1739
1903
  Before finishing any change here:
1740
1904
 
1741
1905
  **Structure**
@@ -1750,16 +1914,24 @@ Before finishing any change here:
1750
1914
 
1751
1915
  **Prompts**
1752
1916
 
1753
- - [ ] `INSTRUCTIONS.md` carries the shared architecture and nothing agent-specific
1754
- - [ ] Nothing duplicated between `INSTRUCTIONS.md` and an agent prompt
1917
+ - [ ] `agents/instructions.md` carries the shared architecture and nothing
1918
+ agent-specific
1919
+ - [ ] Nothing duplicated between a house-rules file and an agent prompt
1920
+ - [ ] Each `agents/<topic>-instructions.md` is about one capability, and is true
1921
+ of every agent
1755
1922
  - [ ] Every tool and agent referenced by its exact name
1756
1923
  - [ ] Failure paths stated for every instruction that can fail
1757
1924
  - [ ] No facts, rates or figures embedded in a prompt
1758
1925
  - [ ] No hedging, no meta-talk about the runtime
1926
+ - [ ] If any agent has `memory:`,
1927
+ `.github/skills/zen-memory/scripts/check-instructions.sh` exits zero -
1928
+ `agents/memory-instructions.md` is the reference byte for byte - and
1929
+ anything project-specific is in `agents/memory-policy-instructions.md` - §5.3
1759
1930
 
1760
- **Paths (§2.5 - run its checklist over the three trees)**
1931
+ **Paths (§2.5 - `.github/skills/zen-review/scripts/check-paths.sh` finds the
1932
+ candidates; these are the judgements to make about each one)**
1761
1933
 
1762
- - [ ] Every absolute path in `INSTRUCTIONS.md`, `agents/prompts/*.md` and
1934
+ - [ ] Every absolute path in `agents/*instructions.md`, `agents/prompts/*.md` and
1763
1935
  `agents/skills/*/SKILL.md` is under `/workspace`, `/assets`, `/skills` or
1764
1936
  `/memory`
1765
1937
  - [ ] No prompt or skill names a project file - `agents.yaml`, a prompt path, a
@@ -1776,10 +1948,17 @@ Before finishing any change here:
1776
1948
  - [ ] Catalog >~30 entries → `discovery: search`
1777
1949
  - [ ] A skill that ships a script writes its `/skills/<name>/...` path, the agent
1778
1950
  holds `sandbox:*`, and the sandbox image already has the interpreter
1951
+ - [ ] A skill whose procedure needs particular tools, an index or a mounted file
1952
+ opens by naming them and says what to do without them - rather than naming
1953
+ the agents allowed to load it, which `agents.yaml` already decides - §0.1
1779
1954
 
1780
1955
  **Tools**
1781
1956
 
1782
1957
  - [ ] Every agent holds the narrowest set its job needs
1958
+ - [ ] Every `tools:` list is a group selector minus its exceptions, not an
1959
+ enumeration of individual names - §3.5
1960
+ - [ ] No agent holds `write_file` without `apply_patch`, or `read_file` without
1961
+ `list_dir` and `find_files`
1783
1962
  - [ ] An agent that only reads is not holding `write_file`, `apply_patch`,
1784
1963
  `move_file` or `delete_file` - subtract them from `workspace:*`
1785
1964
  - [ ] `sandbox:*` is granted only where a shell is actually needed
@@ -1807,14 +1986,29 @@ Before finishing any change here:
1807
1986
  - [ ] No key literal in YAML, prompt, skill or log - `${VAR}` only
1808
1987
  - [ ] `.env` is git-ignored
1809
1988
 
1989
+ **Specification** (only where the project has a `SPECIFICATION.md`)
1990
+
1991
+ - [ ] `.github/skills/zen-spec-sync/scripts/snapshot.sh status` does not say
1992
+ `tampered` - the baseline matches its own `manifest.txt`
1993
+ - [ ] `.spec-sync/baseline/applied.txt` names the newest file in
1994
+ `.spec-sync/history/`; a baseline ahead of the history is a pass that
1995
+ claimed work it did not finish
1996
+ - [ ] The newest history entry's `Still open` is what the next pass will trust,
1997
+ and says so honestly - an unchanged specification line is not evidence
1998
+ that anything implements it
1999
+ - [ ] No question in `SPECIFICATION-FEEDBACK.md` has a box marked `[x]`, or
2000
+ exactly one answer left under it, without a matching `✅ Answered` entry -
2001
+ that is an answer given and never folded into the specification
2002
+ - [ ] `.spec-sync/` is committed and `.tmp/` is not
2003
+
1810
2004
  ---
1811
2005
 
1812
2006
  ## 10. Where to change what
1813
2007
 
1814
2008
  | Symptom | Change this |
1815
2009
  | --------------------------------------------- | ------------------------------------------------------------------- |
1816
- | Wrong tone, wrong format, wrong length | `INSTRUCTIONS.md` (all agents) or the agent prompt |
1817
- | Says something forbidden | `INSTRUCTIONS.md` prohibition, stated specifically |
2010
+ | Wrong tone, wrong format, wrong length | The house rules (all agents) or the agent prompt |
2011
+ | Says something forbidden | A house-rules prohibition, stated specifically |
1818
2012
  | Ignores a rule that only applies sometimes | Move the rule into a skill with a sharp description |
1819
2013
  | Never loads the skill it should | The skill's `description`; or `preload` it |
1820
2014
  | Loads too much, answers slowly | `allow:`, `maxIndexEntries:`, or `discovery: search` |
@@ -1841,6 +2035,8 @@ Before finishing any change here:
1841
2035
  | Fails only on genuinely hard cases | Promote that agent's tier, or split the hard path out |
1842
2036
  | Shows no reasoning while it works | Turn summaries on for that model - §7.6 |
1843
2037
  | Forgets across conversations | Continue the session rather than starting a new one |
2038
+ | Greps `/memory` or reads `graph.json` | `agents/memory-instructions.md` is missing the block - §5.3 |
2039
+ | Recalls a note it cannot check or continue | Same block: it is what requires provenance on every node - §5.3 |
1844
2040
  | Breaks at load with a named path | Read the message - it names the exact key |
1845
2041
 
1846
2042
  ---
@@ -1850,16 +2046,23 @@ Before finishing any change here:
1850
2046
  - **The mega-prompt.** 300 lines covering twelve scenarios. Split into skills.
1851
2047
  - **Agent sprawl.** Eight agents that share one model, one tool set and one
1852
2048
  prompt style. Collapse into one with a catalog.
1853
- - **Facts in prompts.** A fee schedule inside `INSTRUCTIONS.md`. It cannot be
1854
- versioned, cannot be shared, and is paid for on every call.
2049
+ - **Facts in prompts.** A fee schedule inside `agents/instructions.md`. It cannot
2050
+ be versioned, cannot be shared, and is paid for on every call.
1855
2051
  - **The bare skill file.** `agents/skills/<name>.md` instead of a folder. It can
1856
2052
  never grow the table or script the next revision of the rule will want - §3.4.
1857
2053
  - **Pointing an agent at the project.** A prompt or skill naming `agents.yaml`,
1858
- `INSTRUCTIONS.md`, `agents/skills/<name>/…` or `sandbox/Dockerfile`. None of
1859
- them are on any path the agent can open, so the instruction fails on the turn
1860
- that follows it - §2.5.
2054
+ `agents/instructions.md`, `agents/skills/<name>/…` or `sandbox/Dockerfile`.
2055
+ None of them are on any path the agent can open, so the instruction fails on
2056
+ the turn that follows it - §2.5.
1861
2057
  - **Arithmetic in prose.** A skill that walks the model through a calculation it
1862
2058
  will get wrong, in a folder that could have held the script - §3.4.1.
2059
+ - **The unguarded store.** `memory:` turned on and the skill's
2060
+ `references/memory-instructions.md` never copied to
2061
+ `agents/memory-instructions.md`, so nothing tells the agent the store is
2062
+ reached only through the tools - and `zen check` passes throughout - §5.3.
2063
+ - **Reviewing a capability without its skill.** A project whose memory, index or
2064
+ sandbox was configured by an earlier pass looks finished because it loads. The
2065
+ obligations are in the editor skill, not in `agents.yaml` - §0.1.
1863
2066
  - **Politeness padding.** "Please try your best to be helpful." Costs tokens,
1864
2067
  changes nothing.
1865
2068
  - **Commented implementation notes.** `agents.yaml` explaining how skill
@@ -1875,7 +2078,7 @@ Before finishing any change here:
1875
2078
  branch needs the first branch's answer is a sequence wearing a fork's clothes.
1876
2079
  - **Installing the toolchain every run.** A prompt that begins with `apt-get
1877
2080
  install` is an `image:` that was never set - §3.7.
1878
- - **Volatile prefix.** "Current date: …" in `INSTRUCTIONS.md`. Permanent cache
2081
+ - **Volatile prefix.** "Current date: …" in the house rules. Permanent cache
1879
2082
  miss.
1880
2083
 
1881
2084
  ---
@@ -1894,6 +2097,22 @@ Update it when:
1894
2097
  - a vendor trap is discovered - add it to §7.7
1895
2098
  - a recurring review comment appears twice - turn it into a checklist line in §9
1896
2099
  - a runtime capability is added - describe it here, or it will not be used
2100
+ - an editor skill starts requiring a block in the target project - name the
2101
+ requirement in §0.1 and the check for it in §9, or it will be missed
1897
2102
 
1898
2103
  Do not let it grow without pruning. When a section is only true of one agent, it
1899
2104
  belongs in that agent's prompt, not here.
2105
+ ---
2106
+
2107
+ ## 13. Function calling rules
2108
+
2109
+ Before every tool call, write **one line** saying what you are about to do and
2110
+ why. One line per call, in front of it - not a plan for the whole turn, and not
2111
+ a summary afterwards.
2112
+
2113
+ - Say the intent and the reason, not the tool's name or its arguments:
2114
+ _"Reading `agents.yaml` to see which agents hold `sandbox:*`."_
2115
+ - When several calls go out together, write one line covering the batch.
2116
+ - Keep it to a sentence. If it needs two, the call needs splitting, not the
2117
+ sentence.
2118
+ - Do not narrate the result in the same line - the tool answers that.