@zenera/cli 1.1.15 → 1.1.17

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 (57) hide show
  1. package/README.md +201 -129
  2. package/dist/banner.d.ts +5 -1
  3. package/dist/banner.js +2 -2
  4. package/dist/catalog.js +19 -20
  5. package/dist/command.d.ts +5 -0
  6. package/dist/commands/check.js +5 -1
  7. package/dist/commands/init.js +41 -6
  8. package/dist/commands/run.js +4 -0
  9. package/dist/engine.js +6 -0
  10. package/dist/env.d.ts +20 -0
  11. package/dist/env.js +65 -0
  12. package/dist/keys.d.ts +2 -0
  13. package/dist/keys.js +2 -0
  14. package/dist/main.js +10 -6
  15. package/dist/sandbox.d.ts +9 -0
  16. package/dist/sandbox.js +23 -3
  17. package/dist/scaffold.d.ts +6 -0
  18. package/dist/scaffold.js +56 -15
  19. package/dist/validate.js +57 -15
  20. package/package.json +2 -2
  21. package/templates/editor/.github/copilot-instructions.md +501 -301
  22. package/templates/editor/.github/prompts/new-agent.prompt.md +6 -6
  23. package/templates/editor/.github/prompts/new-skill.prompt.md +7 -7
  24. package/templates/editor/.github/prompts/review-project.prompt.md +54 -15
  25. package/templates/editor/.github/prompts/sync-with-spec.prompt.md +229 -42
  26. package/templates/editor/.github/prompts/update-spec-from-feedback.prompt.md +142 -0
  27. package/templates/editor/.github/skills/zen-cli/SKILL.md +62 -6
  28. package/templates/editor/.github/skills/zen-cli/references/check.md +9 -6
  29. package/templates/editor/.github/skills/zen-cli/references/faker.md +14 -14
  30. package/templates/editor/.github/skills/zen-cli/references/frame.md +11 -9
  31. package/templates/editor/.github/skills/zen-cli/references/inspect.md +3 -3
  32. package/templates/editor/.github/skills/zen-cli/references/keys.md +9 -9
  33. package/templates/editor/.github/skills/zen-cli/references/memory.md +11 -11
  34. package/templates/editor/.github/skills/zen-cli/references/models.md +8 -8
  35. package/templates/editor/.github/skills/zen-cli/references/projects.md +23 -6
  36. package/templates/editor/.github/skills/zen-cli/references/rag.md +191 -56
  37. package/templates/editor/.github/skills/zen-cli/references/run.md +3 -3
  38. package/templates/editor/.github/skills/zen-cli/references/sandbox.md +14 -8
  39. package/templates/editor/.github/skills/zen-memory/SKILL.md +144 -72
  40. package/templates/editor/.github/skills/zen-memory/scripts/check-instructions.sh +115 -0
  41. package/templates/editor/.github/skills/zen-rag-docs/SKILL.md +71 -48
  42. package/templates/editor/.github/skills/zen-rag-schema/SKILL.md +67 -67
  43. package/templates/editor/.github/skills/zen-review/SKILL.md +123 -0
  44. package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +119 -0
  45. package/templates/editor/.github/skills/zen-review/scripts/review.sh +104 -0
  46. package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +197 -0
  47. package/templates/editor/.github/skills/zen-spec-sync/scripts/snapshot.sh +200 -0
  48. package/templates/editor/.vscode/settings.json +46 -3
  49. package/templates/parts/memory-terms.yaml.tmpl +16 -0
  50. package/templates/parts/memory.yaml.tmpl +12 -0
  51. package/templates/project/SPECIFICATION.md.tmpl +7 -0
  52. package/templates/project/{INSTRUCTIONS.md → agents/instructions.md} +1 -1
  53. package/templates/project/agents/memory-instructions.md +278 -0
  54. package/templates/project/agents.yaml.tmpl +9 -0
  55. package/templates/project/assets/README.md +1 -1
  56. package/templates/project/env +22 -0
  57. package/templates/project/sandbox/Dockerfile.tmpl +3 -0
@@ -14,8 +14,8 @@ true, and you should say which:
14
14
  - its instructions **contradict** an existing agent's rather than extend them
15
15
  - it is a **parallel branch** target for a `fork:`
16
16
 
17
- If none holds, propose the smaller change instead — a skill, a prompt line, a
18
- tool grant — and stop. Adding an agent to solve a prompt problem is the failure
17
+ If none holds, propose the smaller change instead - a skill, a prompt line, a
18
+ tool grant - and stop. Adding an agent to solve a prompt problem is the failure
19
19
  mode this project cares most about.
20
20
 
21
21
  If it is warranted:
@@ -23,18 +23,18 @@ If it is warranted:
23
23
  1. Pick a name matching `^[a-z0-9]+(?:[-_][a-z0-9]+)*$`. It reaches the model as
24
24
  `transfer_to_<name>`, so the name is part of the routing surface.
25
25
  2. Write `agents/prompts/<name>.md`: one sentence of identity, a short procedure
26
- or three to five rules, then what it must **not** do — especially the
26
+ or three to five rules, then what it must **not** do - especially the
27
27
  neighbouring agent's job. Second person, imperative, failure paths stated.
28
28
  No frontmatter, no meta-talk about the runtime.
29
- 3. Add the `agents.yaml` entry. `description:` is written **for the model** — it
29
+ 3. Add the `agents.yaml` entry. `description:` is written **for the model** - it
30
30
  is the whole of what a sibling sees when deciding to hand off. Grant the
31
31
  narrowest `tools:` the job needs.
32
32
  4. Wire the return edge. A handoff does not come back on its own, so every
33
- `A → B` needs a path from B back to A — directly, or through another agent.
33
+ `A → B` needs a path from B back to A - directly, or through another agent.
34
34
  `zen check` warns on an edge that has none. If what this agent really wants
35
35
  is an _answer_ rather than to give up the conversation, declare `fork:`
36
36
  instead: a branch returns by itself.
37
- 5. Add a one-line comment above the entry saying why this agent exists — its
37
+ 5. Add a one-line comment above the entry saying why this agent exists - its
38
38
  job or its tier, not what the keys mean.
39
39
 
40
40
  Then run `zen check` and report what it said. If it fails, fix the file it
@@ -3,29 +3,29 @@ mode: agent
3
3
  description: Add a skill under agents/skills, with a description that routes.
4
4
  ---
5
5
 
6
- Add a skill to this project. A skill is curated instruction content — and
7
- optionally tools — loaded on demand instead of sitting in every system prompt.
6
+ Add a skill to this project. A skill is curated instruction content - and
7
+ optionally tools - loaded on demand instead of sitting in every system prompt.
8
8
  Reach for one whenever a rule applies only sometimes, or holds a fact that will
9
9
  change without the prompt changing.
10
10
 
11
11
  Ask what the skill must say and when it applies, if I have not already said.
12
12
 
13
13
  1. Create `agents/skills/<name>/SKILL.md`. That is the only skill layout there
14
- is — a bare `agents/skills/<name>.md` fails `zen check` — and the folder is
14
+ is - a bare `agents/skills/<name>.md` fails `zen check` - and the folder is
15
15
  what lets the skill carry companions later: a rate table, an example letter,
16
16
  a schema, a script.
17
17
  2. Write the `description`. This is the routing key and the only thing the model
18
18
  sees before deciding to load the skill, so write it as **the condition under
19
19
  which the skill is needed**, not as a title. `Water policy` is a title;
20
- `Escape of water from plumbing and tanks — and the freezing exclusion` is a
20
+ `Escape of water from plumbing and tanks - and the freezing exclusion` is a
21
21
  condition. If two skills could both match a case, sharpen both until they
22
22
  cannot.
23
23
  3. Write the body as instructions the model can act on: thresholds, exact
24
24
  wording, the boundaries of the rule, and what to do when the case falls
25
- outside it. Put the facts here rather than in a prompt — that is the point of
25
+ outside it. Put the facts here rather than in a prompt - that is the point of
26
26
  the file.
27
27
  4. Put anything the rule computes or looks up in a file beside `SKILL.md` and
28
- name it from the body by its absolute path — `python
28
+ name it from the body by its absolute path - `python
29
29
  /skills/<name>/scripts/calculate.py <id>`, not `scripts/calculate.py`. The
30
30
  folder is mounted read-only at `/skills/<name>/`, so the script writes
31
31
  nothing there; the agent needs `sandbox:*` to run it, and the interpreter has
@@ -37,7 +37,7 @@ Ask what the skill must say and when it applies, if I have not already said.
37
37
  6. Leave `name` out unless it must differ from the folder name, and leave
38
38
  `version`/`tags` out unless something uses them.
39
39
 
40
- Do not `preload:` it unless every case genuinely needs it — a preloaded skill is
40
+ Do not `preload:` it unless every case genuinely needs it - a preloaded skill is
41
41
  a longer prompt, paid for on every call. Bind it under `agents[].skills.allow`
42
42
  if the agent's catalog is restricted.
43
43
 
@@ -4,32 +4,71 @@ description: Review the project against the checklist before committing.
4
4
  ---
5
5
 
6
6
  Review this project the way a maintainer would, then report. Read
7
- `agents.yaml`, `INSTRUCTIONS.md`, every file under `agents/prompts/` and the
8
- skill descriptions under `agents/skills/` before saying anything.
7
+ `agents.yaml`, every `agents/*instructions.md`, every file under
8
+ `agents/prompts/` and the skill descriptions under `agents/skills/` before
9
+ saying anything.
9
10
 
10
- Work the checklist in §9 of the copilot instructions. In particular:
11
+ **Run the mechanical checks first, and report what they say:**
12
+
13
+ ```sh
14
+ .github/skills/zen-review/scripts/review.sh
15
+ ```
16
+
17
+ That is `zen check`, the §2.5 path sweep, the memory house-rules copy and the
18
+ spec-sync record, in the order they matter. Load the `zen-review` skill for what
19
+ each one owns and how to read its output. Do not re-verify by hand anything it
20
+ already decided, and do not go further while `zen check` fails - nothing below
21
+ matters until it passes.
22
+
23
+ **Then list the capabilities this project turns on** — a `memory:` block, a
24
+ `zen rag` index, a sandbox, a `SPECIFICATION.md` — and load the editor skill
25
+ for each before judging it. The obligations live in the skill, not in
26
+ `agents.yaml`, and `zen check` reports none of them. A capability that is
27
+ already configured and already passing is exactly the case that looks finished
28
+ and is not.
29
+
30
+ Everything that follows is what no tool can see:
11
31
 
12
- - **Loads.** Run `zen check`. Nothing else in this review matters if it fails.
13
32
  - **One job each.** Can you state every agent's job in one sentence? If not,
14
33
  say which agent and what the two jobs are.
15
34
  - **Prompts.** Second person, imperative, failure paths stated, no hedging, no
16
- politeness padding, no meta-talk about the runtime. Nothing in
17
- `INSTRUCTIONS.md` that is true of only one agent.
35
+ politeness padding, no meta-talk about the runtime. Nothing in the house rules
36
+ that is true of only one agent, and nothing in `agents/instructions.md` that
37
+ belongs in a `<topic>-instructions.md` of its own because it only applies when
38
+ one capability is on.
18
39
  - **Facts.** Any number, threshold, fee or date living in a prompt is in the
19
40
  wrong file. Name it and say which skill it belongs in.
20
- - **Paths.** Work the checklist in §2.5 over `INSTRUCTIONS.md`,
21
- `agents/prompts/*.md` and `agents/skills/*/SKILL.md`. Every absolute path must
22
- be under `/workspace`, `/assets`, `/skills` or `/memory`; nothing may name a
23
- project file the agent cannot open, and nothing may assume the workspace is
24
- this directory.
41
+ - **Paths.** For each candidate `check-paths.sh` printed: is it a path the
42
+ agent cannot open, or noise? Say which, and for a real one say what it should
43
+ have been. Judge the rest of the §2.5 checklist yourself — that no instruction
44
+ assumes the workspace is this directory, that every `/assets/…` and
45
+ `/skills/<name>/…` names a committed file, and that the agent holding the
46
+ prompt has the tool the path implies.
47
+ - **Memory.** Anything this project decides for itself belongs in
48
+ `agents/memory-policy-instructions.md`, not in the copy — and it should say
49
+ something. Audiences that exist because an agent would be _misled_ by the
50
+ other slice, not merely because it does not need it.
25
51
  - **Skill descriptions.** Each one a condition, not a title; no two overlapping.
52
+ Every skill a folder with a `SKILL.md`, and a skill that ships a script writes
53
+ its `/skills/<name>/…` path.
26
54
  - **Tools.** Every grant justified by the agent's job; nothing mutating held by
27
- an agent that only reads; every granted tool mentioned by the prompt.
28
- - **Routing.** Handoff targets have descriptions written for the model. No
29
- ping-pong edges. No router that answers.
55
+ an agent that only reads; every granted tool mentioned by the prompt. An agent
56
+ with no `skills:` key indexes the whole catalog - check that every agent can
57
+ actually follow the skills it is offered.
58
+ - **Sandbox.** `persist: true` unless a throwaway rootfs is wanted on purpose.
59
+ What the work always needs is in the image, not installed by a prompt on every
60
+ run.
61
+ - **Control flow.** Whichever this project uses. A handoff moves the
62
+ conversation and must have a path back; a fork returns by itself and condenses
63
+ to one result, so whatever the caller needs must be in the branch's answer.
64
+ Wanting one lookup and spending the conversation on it is a fork, not a
65
+ handoff. No router that answers.
30
66
  - **Models.** Each agent on the cheapest tier that is right, not the safest.
31
- - **Cache.** Nothing volatile — dates, ids, counts — in the stable prefix.
67
+ - **Cache.** Nothing volatile - dates, ids, counts - in the stable prefix.
32
68
  - **Secrets.** No key inlined anywhere; `.env` ignored, `sessions/` ignored.
69
+ - **Specification.** Where a `SPECIFICATION.md` exists, `review.sh` reported the
70
+ record's mode. Judge the rest: the newest history entry's "Still open" is
71
+ honest, its baseline names that entry, and `.spec-sync/` is committed.
33
72
 
34
73
  Report as a list of findings, each naming the file and the line, ordered by how
35
74
  much it will cost to leave. Say plainly if you find nothing worth changing.
@@ -3,24 +3,55 @@ description: Bring the project into compliance with SPECIFICATION.md, and record
3
3
  ---
4
4
 
5
5
  Make this project match `SPECIFICATION.md`. The specification is the intent;
6
- the files are the implementation. Where they disagree, the specification wins —
6
+ the files are the implementation. Where they disagree, the specification wins -
7
7
  except where it is ambiguous, contradictory or impossible, which is what
8
8
  `SPECIFICATION-FEEDBACK.md` is for.
9
9
 
10
+ ## 0. Decide the size of this pass
11
+
12
+ Load the `zen-spec-sync` skill first, before anything else and whatever state
13
+ the project is in - a project with no baseline is the one that needs it most,
14
+ because this pass has to make the first. Then, from the project root:
15
+
16
+ ```sh
17
+ .github/skills/zen-spec-sync/scripts/snapshot.sh status
18
+ .github/skills/zen-spec-sync/scripts/snapshot.sh diff
19
+ ```
20
+
21
+ `status` answers `full`, `incremental` or `tampered`. Say which in the chat
22
+ before reading anything, and on an incremental pass state the scope you drew
23
+ from the diffs - the skill says how. `full` and `tampered` both mean the whole
24
+ prompt as written below, from nothing.
25
+
26
+ The diff covers both sides. `SPECIFICATION.md` and `SPECIFICATION-FEEDBACK.md`
27
+ say what has been **asked for** since the last pass; `agents.yaml` and every
28
+ file under `agents/` say what has been **built or hand-edited** since then. The
29
+ first narrows the pass to the work nobody has done; the second only widens it,
30
+ because a prompt or skill someone changed outside a pass still has to be
31
+ accounted for against the specification.
32
+
33
+ The scope decides what you **read and edit**. It never decides what you
34
+ **verify**: §6, §7 and the four checks in the skill run at full size on every
35
+ pass, however small the diff.
36
+
10
37
  ## 1. Read before changing anything
11
38
 
12
39
  Read, in this order, and do not edit until all of it is read:
13
40
 
14
- 1. `SPECIFICATION.md` — what the system is meant to be.
15
- 2. `agents.yaml` — providers, models, embeddings, agents, tools, handoffs,
41
+ 1. `SPECIFICATION.md` - what the system is meant to be.
42
+ 2. `agents.yaml` - providers, models, embeddings, agents, tools, handoffs,
16
43
  skills, sandbox.
17
- 3. `INSTRUCTIONS.md` and every file under `agents/prompts/`.
44
+ 3. Every `agents/*instructions.md` and every file under `agents/prompts/`.
18
45
  4. Every `agents/skills/*/SKILL.md`, plus what each skill folder ships.
19
46
  5. `assets/`, `sandbox/Dockerfile` and every script under `scripts/`, starting
20
47
  with `scripts/_setup.sh`.
21
- 6. `SPECIFICATION-FEEDBACK.md`, if it exists — do not re-raise something already
48
+ 6. `SPECIFICATION-FEEDBACK.md`, if it exists - do not re-raise something already
22
49
  open there.
23
50
 
51
+ On an incremental pass this list narrows to the artefacts the scope implicates,
52
+ and to the changed hunks of the specification rather than all of it. The
53
+ narrowing is a claim: name what you skipped and why the diff does not reach it.
54
+
24
55
  Run `zen check` first and record what it said. A project that does not load is
25
56
  the first thing to fix.
26
57
 
@@ -29,11 +60,11 @@ the first thing to fix.
29
60
  Produce a difference list before touching a file. For every item in the
30
61
  specification, decide which of these it is:
31
62
 
32
- - **present and correct** — leave it alone
33
- - **missing** — the specification asks for it and nothing implements it
34
- - **divergent** — implemented, but not as specified
35
- - **extra** — implemented, and the specification does not ask for it
36
- - **unclear** — the specification does not say enough to implement it
63
+ - **present and correct** - leave it alone
64
+ - **missing** - the specification asks for it and nothing implements it
65
+ - **divergent** - implemented, but not as specified
66
+ - **extra** - implemented, and the specification does not ask for it
67
+ - **unclear** - the specification does not say enough to implement it
37
68
 
38
69
  Check at least: the model and embedding ids and which agent uses which; that
39
70
  every agent named in the specification exists with that job and no second job;
@@ -41,25 +72,31 @@ handoff edges and fork permissions; the tools each agent holds; every skill the
41
72
  specification implies; and every setup step, index or asset it depends on.
42
73
 
43
74
  Then build the difference the other way, because the list above can only find
44
- what the specification asked for and nothing implements. Read `INSTRUCTIONS.md`,
45
- each `agents/prompts/*.md` and each `SKILL.md` **line by line**, and for every
46
- line name the specification item it serves. A line serving none is an **extra** —
47
- the category covers a single sentence in a prompt, not only a whole file. Three
48
- things to look for while reading, none of which the forward pass can see:
75
+ what the specification asked for and nothing implements. Read every
76
+ `agents/*instructions.md`, each `agents/prompts/*.md` and each `SKILL.md` **line
77
+ by line**, and for every line name the specification item it serves. A line
78
+ serving none is an **extra** - the category covers a single sentence in a prompt,
79
+ not only a whole file. Three things to look for while reading, none of which the
80
+ forward pass can see:
49
81
 
50
82
  - **A line that contradicts another file.** One prompt against another, a prompt
51
- against `INSTRUCTIONS.md`, or a prompt against `agents.yaml` — an instruction
83
+ against the house rules, or a prompt against `agents.yaml` - an instruction
52
84
  to use a tool the agent does not hold, to hand to an agent that is not in its
53
85
  `handoffs:`, or to load a skill outside its `allow:`.
54
86
  - **A line that asks for something the system already supplies.** A question put
55
87
  to the user about a value that arrives from the environment, a file or an
56
88
  earlier step is unanswerable, and the answer would be discarded.
57
- - **A line the agent cannot carry out** — naming a path it cannot reach, a tool
89
+ - **A line the agent cannot carry out** - naming a path it cannot reach, a tool
58
90
  it was not granted, or an agent it cannot transfer to.
59
91
 
60
92
  These are bugs whatever the specification says: fix them in place and report each
61
93
  one. An extra that is merely unspecified is reported under `➕`, not removed.
62
94
 
95
+ On an incremental pass this reverse reading covers every file this pass touched
96
+ plus every file the implementation diff in §0 named - an edit made in this
97
+ session, or made by hand since the last pass, is exactly where a fresh
98
+ contradiction comes from. On a full pass it is the whole tree, as above.
99
+
63
100
  ## 3. Change the smallest thing that closes the gap
64
101
 
65
102
  Apply the fixes in the order the copilot instructions prefer: a prompt or skill
@@ -83,19 +120,19 @@ the model to compute or remember. Specifically:
83
120
  Never delete an **extra** without saying so. Report it, say why the
84
121
  specification does not cover it, and leave it unless I tell you to remove it.
85
122
 
86
- Do not invent a value the specification does not state — a model id, a limit, a
123
+ Do not invent a value the specification does not state - a model id, a limit, a
87
124
  retry count, a file path. That is an entry in `SPECIFICATION-FEEDBACK.md`, not a
88
125
  guess.
89
126
 
90
127
  ## 4. Every setup step is a script
91
128
 
92
- Anything the project needs done before it can run — building an index, fetching
93
- a document, generating a file, warming the sandbox image — is a shell script,
129
+ Anything the project needs done before it can run - building an index, fetching
130
+ a document, generating a file, warming the sandbox image - is a shell script,
94
131
  not a paragraph of instructions for a human.
95
132
 
96
133
  - One step per file, under `scripts/`, named after the step:
97
134
  `scripts/build-schema-index.sh`, `scripts/fetch-api-docs.sh`.
98
- - `scripts/_setup.sh` is the **only** entry point — the leading underscore is
135
+ - `scripts/_setup.sh` is the **only** entry point - the leading underscore is
99
136
  what separates the runner from the steps it runs. It runs the steps in the
100
137
  order they depend on each other and is the single command that initialises the
101
138
  project. `zen init` writes it; adding a step is adding `scripts/<name>.sh` and
@@ -114,7 +151,7 @@ not a paragraph of instructions for a human.
114
151
  - **It must be watchable.** `scripts/_setup.sh` tees each step's output to
115
152
  `.tmp/logs/setup-<step>.log`, prints a heartbeat line while a long step runs,
116
153
  and finishes with one line per step: `ok`, `skipped`, or `failed`.
117
- - **Everything transient goes under `.tmp/`** — logs, scratch files, downloads,
154
+ - **Everything transient goes under `.tmp/`** - logs, scratch files, downloads,
118
155
  test output, and the temporary path a step writes to before moving its
119
156
  artefact into place. Nothing else in the tree is a scratch directory, and
120
157
  `.tmp/` is git-ignored: add it to `.gitignore` if it is not there already.
@@ -132,44 +169,175 @@ anything in the
132
169
  specification is unclear, contradictory, impossible, or wrong. If there is
133
170
  nothing to raise, say so in the chat and do not create the file.
134
171
 
135
- Group entries under these headings, and omit a heading that has no entries.
136
- The file is scanned before it is read, so keep the emoji on every heading:
172
+ **It is a questionnaire, and answering it must take one gesture.** Every
173
+ question carries two to four written-out answers, each with a `[ ]` box in its
174
+ heading. The reader marks the box of the one they want - `[x]` - and deletes the
175
+ others, then sends `/update-spec-from-feedback`, which folds what survived into
176
+ `SPECIFICATION.md`. Either gesture alone is enough, and the file says so in
177
+ every question.
178
+
179
+ Two rules that come before everything else in this section:
180
+
181
+ - **No markdown tables anywhere in this file.** A table is unreadable the moment
182
+ a pane is narrow or a cell wraps, and this is a file people read in a side
183
+ panel. Every list is a list.
184
+ - **Never write a question the reader has to do work to answer.** No paragraph
185
+ ending in "is that what you meant?", nothing that requires reading the
186
+ implementation, and no answer phrased as a decision still to be made. If you
187
+ cannot write two answers a reader could pick between, you have not understood
188
+ the problem well enough to ask about it yet.
189
+
190
+ The file opens with one short paragraph: how many questions are open, and how to
191
+ answer them - put an `x` in the box of the answer you want, delete the answers
192
+ you do not want, or replace them all with a sentence of your own, then send
193
+ `/update-spec-from-feedback`. Then a contents list, one line per question: its
194
+ number as an anchor link, the question in under ten words, and what is built in
195
+ the meantime. Then the questions, grouped under these headings, omitting any
196
+ heading with no questions. The file is scanned before it is read, so keep the
197
+ emoji on every heading:
137
198
 
138
199
  ```markdown
139
200
  # Feedback on SPECIFICATION.md
140
201
 
141
- ## 🛑 Blocking — cannot implement without an answer
202
+ ## 🛑 Blocking - cannot implement without an answer
142
203
 
143
- ## ❓ Ambiguous — implemented one way, confirm the choice
204
+ ## ❓ Ambiguous - implemented one way, confirm the choice
144
205
 
145
206
  ## ⚡ Contradictions
146
207
 
147
208
  ## ✏️ Errors and typos
148
209
 
149
- ## ➕ Out of scope — implemented but unspecified
210
+ ## ➕ Out of scope - implemented but unspecified
211
+
212
+ ## ✅ Answered - folded into the specification
213
+ ```
214
+
215
+ `✅` is written by `/update-spec-from-feedback`, not by you. Leave what is there
216
+ alone except to strike an entry this pass has actually implemented, and say in
217
+ the chat which ones you closed.
218
+
219
+ ### The shape of one question
220
+
221
+ Each question is its own `###` heading - the emoji of its section, `Q` and a
222
+ number, then the question itself, ending in a question mark. Under it, in this
223
+ order:
224
+
225
+ - **Where it comes from** - the specification text quoted as a blockquote,
226
+ introduced by a link to the exact line,
227
+ `[SPECIFICATION.md#L66](SPECIFICATION.md#L66)`, plus the section name. Link
228
+ every line you quote; a reader must reach it in one click. For a question
229
+ about something the specification does not say at all, link the section it
230
+ would belong to and say that it is silent there.
231
+ - **Why it is a problem** - two or three sentences on what goes wrong, in terms
232
+ of behaviour: what an agent does, what a run produces, what breaks. Not
233
+ "unclear" or "ambiguous", which describe the sentence rather than the damage.
234
+ - **Built in the meantime** - what the implementation does now, and the one fact
235
+ that made it the default. Or "Nothing - blocked."
236
+ - **To answer** - the same sentence on every question, word for word: put an `x`
237
+ in one box below and delete the other answers, either one is enough.
238
+
239
+ Then two to four answers, each its own `####` heading of the form
240
+ `#### [ ] A. <the answer in one line, as the reader would say it>`. The one that
241
+ is implemented comes first and is marked `_(built)_`, so the file reads as "this
242
+ is what happens if you change nothing"; mark one `_(recommended)_` where it is
243
+ better for a reason the reader can check. Under each answer heading:
244
+
245
+ - **What it changes** - one or two sentences on the consequence of choosing it:
246
+ what the system would then do differently, and what it costs.
247
+ - **The specification text**, in a fenced block, introduced by where it goes -
248
+ "replace line 66", "add after line 21", "delete lines 30-32". Written in the
249
+ specification's own voice and format so it can be pasted without editing.
250
+
251
+ Every answer carries its own box and its own text. They are alternatives that
252
+ will be read alone, so nothing may be shared between them and nothing may refer
253
+ to a sibling ("as above", "same as A"). Where an answer needs a value only the
254
+ reader has, put a `<placeholder>` in the block and say in **What it changes**
255
+ what to substitute.
256
+
257
+ Two rules on the answers themselves:
258
+
259
+ - **An answer is a real alternative**, not a restatement of the question or a
260
+ hedge. "Decide later" is not an answer; "leave it unspecified, and the
261
+ reviewer keeps using whatever the default agent uses" is.
262
+ - **Never write only one answer.** A question with nothing to choose between is
263
+ not a question. Even an `✏️` typo has two: the correction, and leaving it as
264
+ written with a line saying what stays wrong.
265
+
266
+ Under `➕` the two answers are fixed: keep it, whose block is the specification
267
+ text that would cover what was built, and remove it, whose **What it changes**
268
+ says what removing it would cost and which files would go.
269
+
270
+ ### One question, written out
271
+
272
+ Copy this shape exactly - the outer fence is four backticks only so the example
273
+ can contain its own:
274
+
275
+ ````markdown
276
+ ### ❓ Q4. Do the three agents share one memory, or keep their own?
277
+
278
+ **Where it comes from** - [SPECIFICATION.md#L14](SPECIFICATION.md#L14), _Common
279
+ memory strategies_:
280
+
281
+ > use memory to save plans of answering what was delegated to what
282
+
283
+ **Why it is a problem** - the specification says what each agent writes and
284
+ never says who may read it. Memory is one graph with an audience on every node,
285
+ so this decides whether the orchestrator can plan from what a specialist
286
+ resolved last week, or re-derives it every time.
287
+
288
+ **Built in the meantime** - one shared slice: `memory: true` on all three, so
289
+ anything one agent writes, another can recall. Chosen because nothing in the
290
+ specification separates them.
291
+
292
+ **To answer** - put an `x` in one box below and delete the other answers. Either
293
+ one is enough.
294
+
295
+ #### [ ] A. All three agents share one memory _(built)_
296
+
297
+ **What it changes** - a lookup is paid for once for the whole system, and every
298
+ agent's recall competes with every other agent's notes for the same few slots.
299
+
300
+ Add under _Common memory strategies_, after line 17:
301
+
302
+ ```markdown
303
+ All three agents read and write one shared memory: whatever one of them
304
+ discovers is recallable by the others.
150
305
  ```
151
306
 
152
- Each entry is one bullet, opening with the emoji of the heading it sits under,
153
- then four parts in this order:
307
+ #### [ ] B. Each agent keeps its own memory
154
308
 
155
- - **What the specification says**, quoted, with the section it is in.
156
- - **Why it cannot be implemented as written** — the specific gap, not "unclear".
157
- - **What was done in the meantime**, or "nothing — blocked".
158
- - **The question**, phrased so a one-line answer unblocks it.
309
+ **What it changes** - recall gets sharper and cheaper because an agent only ever
310
+ sees its own kind of note, and the same lookup is repeated by whoever did not do
311
+ it first.
159
312
 
160
- Use no other emoji anywhere in the file — one per entry is what makes them
161
- scannable. Keep entries factual and short. Do not editorialise about the
162
- specification's quality, do not restate the runtime, and do not copy the whole
163
- section in.
164
- Append to the existing file rather than rewriting it; strike an entry only when
165
- this pass has actually resolved it, and say in the chat which ones you closed.
313
+ Add under _Common memory strategies_, after line 17:
314
+
315
+ ```markdown
316
+ Each agent reads and writes only its own memory. A finding one agent needs from
317
+ another travels as part of the hand-off, not through the store.
318
+ ```
319
+ ````
320
+
321
+ Use no emoji except the one on each heading. Keep the prose short. Do not
322
+ editorialise about the specification's quality, do not restate the runtime, and
323
+ do not copy a whole section in.
324
+
325
+ Append to the existing file rather than rewriting it, keeping the numbering and
326
+ the contents list in step. Numbers are never reused: a struck question's number
327
+ retires with it.
328
+
329
+ Read the feedback diff from §0 before writing: a question the human answered
330
+ since the last pass is work to close, not a question to ask again. If a question
331
+ has a box marked `[x]`, or one answer left under it, and no `✅` entry, the
332
+ reader answered it and never ran `/update-spec-from-feedback` - implement that
333
+ answer, fold its text into `SPECIFICATION.md` yourself, and say so in the chat.
166
334
 
167
335
  ## 6. Run `scripts/_setup.sh` and watch it finish
168
336
 
169
337
  After `zen check` passes, run `scripts/_setup.sh` yourself. A pass is not done
170
338
  until it has run to completion in this session.
171
339
 
172
- It is slow — an embedding index is minutes, not seconds — so start it in the
340
+ It is slow - an embedding index is minutes, not seconds - so start it in the
173
341
  background and follow the logs instead of waiting blind:
174
342
 
175
343
  - Tail `.tmp/logs/setup-*.log` and check the output artefact is still growing.
@@ -182,7 +350,7 @@ background and follow the logs instead of waiting blind:
182
350
  - Do not kill a quiet step. Confirm the process is dead or the log and the
183
351
  output have both stopped growing before calling it stuck.
184
352
  - On failure, read that step's log, fix the cause, and run `scripts/_setup.sh`
185
- again — re-running is the fix path, not a reset. If the same step fails twice
353
+ again - re-running is the fix path, not a reset. If the same step fails twice
186
354
  for the same reason, stop and raise it in `SPECIFICATION-FEEDBACK.md`.
187
355
  - Prove re-entrancy: once it has succeeded, run `scripts/_setup.sh` once more and
188
356
  check that every step reports `skipped` rather than rebuilding.
@@ -196,10 +364,29 @@ fail. Then report in the chat:
196
364
 
197
365
  - what changed, file by file, and which specification item each change closes
198
366
  - every prompt or skill line that served no specification item, and what became
199
- of it — corrected, or reported and left alone
367
+ of it - corrected, or reported and left alone
200
368
  - the outcome of every `scripts/_setup.sh` step, and what each one produced
201
369
  - what is still open, with a pointer to its `SPECIFICATION-FEEDBACK.md` entry
202
370
  - anything you found that the specification does not cover at all
203
371
 
372
+ ## 8. Record the pass
373
+
374
+ Last, and only once §6 and §7 have actually passed. Write
375
+ `.spec-sync/history/<stamp>.md` in the format the `zen-spec-sync` skill gives -
376
+ including `Still open`, which is the only place the next pass learns that an
377
+ unchanged specification line is not yet implemented - and then:
378
+
379
+ ```sh
380
+ .github/skills/zen-spec-sync/scripts/snapshot.sh commit
381
+ ```
382
+
383
+ In that order, never the other way. Moving the baseline before the pass has
384
+ finished records a specification as applied that was not: the next pass diffs
385
+ against it, sees nothing to do, and the work is never done by anybody. A pass
386
+ that fails with the baseline unmoved costs one repeat.
387
+
388
+ A pass that changed nothing still writes a history file and still commits. Say
389
+ in the chat which history file you wrote and that the baseline moved.
390
+
204
391
  Do not report a specification item as done unless the file that implements it
205
392
  exists, `zen check` passes, and `scripts/_setup.sh` completed every step it owns.