@zenera/cli 1.1.40 → 1.1.42
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/package.json +4 -4
- package/templates/editor/.github/copilot-instructions.md +7 -3
- package/templates/editor/.github/prompts/spec-sync-project.prompt.md +18 -3
- package/templates/editor/.github/skills/zen-analyze-run/SKILL.md +352 -156
- package/templates/editor/.github/skills/zen-cli/SKILL.md +1 -1
- package/templates/editor/.github/skills/zen-cli/references/frame.md +1 -1
- package/templates/editor/.github/skills/zen-cli/references/gym.md +105 -76
- package/templates/editor/.github/skills/zen-inspect/SKILL.md +15 -0
- package/templates/editor/.github/skills/zen-inspect-ask/SKILL.md +14 -5
- package/templates/editor/.github/skills/zen-review/scripts/check-paths.sh +5 -1
- package/templates/editor/.github/skills/zen-spec-sync/SKILL.md +79 -2
- package/templates/project/agents/memory-instructions.md +14 -0
- package/templates/project/agents/prompts/default.md.tmpl +60 -0
|
@@ -33,7 +33,7 @@ zen version
|
|
|
33
33
|
|
|
34
34
|
zen meta <run|prompts|resume|model|dataset> [project] [args]
|
|
35
35
|
|
|
36
|
-
zen gym <serve|build|cache|model> [spec...]
|
|
36
|
+
zen gym <serve|build|cache|world|model> [spec...]
|
|
37
37
|
zen rag schema <index|restore|ready|search|list|grep|trace|show|stats> [spec...]
|
|
38
38
|
zen rag docs <index|restore|ready|search|list|grep|show|stats> [path...]
|
|
39
39
|
```
|
|
@@ -103,7 +103,7 @@ A real environment variable always beats the keyring.
|
|
|
103
103
|
projects.json the registry: name -> directory
|
|
104
104
|
keys.json credentials (0600)
|
|
105
105
|
keys/ key files, for providers that hold a file
|
|
106
|
-
gym/
|
|
106
|
+
gym/ handlers, worlds, docs indexes and agent reports for `zen gym`
|
|
107
107
|
|
|
108
108
|
<project>/
|
|
109
109
|
zenera.json { version, name }
|
|
@@ -1,126 +1,155 @@
|
|
|
1
1
|
# Agent API environments - `zen gym`
|
|
2
2
|
|
|
3
3
|
```
|
|
4
|
-
zen gym <serve|build|cache|model> [spec...]
|
|
4
|
+
zen gym <serve|build|cache|world|model> [spec...]
|
|
5
5
|
```
|
|
6
6
|
|
|
7
7
|
Provided by `@zenera/gym` - `npm i -g @zenera/gym` if
|
|
8
8
|
`zen gym` says it is not installed.
|
|
9
9
|
|
|
10
|
-
Serves a mock API from
|
|
11
|
-
operation
|
|
12
|
-
|
|
13
|
-
|
|
10
|
+
Serves a mock API from OpenAPI/Swagger documents, backed by a **stateful
|
|
11
|
+
world**. For each operation an agent writes a **TypeScript handler** (the
|
|
12
|
+
mechanics: which type, which filter, what a write changes), judged before it is
|
|
13
|
+
cached. Content comes from a second agent that fills the world on first read,
|
|
14
|
+
following an optional **story** (`--story`) and drawing on **reference
|
|
15
|
+
documents** (`--docs`). Lists and gets agree, writes are seen by later reads,
|
|
16
|
+
and several `zen gym` processes given the same story share one world. No
|
|
17
|
+
container engine is needed.
|
|
18
|
+
|
|
19
|
+
## Inputs
|
|
20
|
+
|
|
21
|
+
Each is a file, a directory or a quoted pattern, and each is repeatable.
|
|
22
|
+
|
|
23
|
+
| Input | What it is | How agents get it |
|
|
24
|
+
| ------------------- | --------------------------------------------------------------------- | --------------------------- |
|
|
25
|
+
| `spec…`, `--schema` | API documents: `.yaml`/`.yml`/`.json` declaring `swagger:`/`openapi:` | API graph and types |
|
|
26
|
+
| `--story` | the state of the world: people, what is happening, what is not | quoted whole in prompts |
|
|
27
|
+
| `--docs` | reference material: knowledge base, guides, runbooks | searched (indexed at start) |
|
|
28
|
+
|
|
29
|
+
A directory given as `--schema` is walked and only real API documents are kept,
|
|
30
|
+
so a folder of mixed JSON — or an API index somebody built — works. A Markdown
|
|
31
|
+
file given as a schema is refused with a hint; so is an API document given as
|
|
32
|
+
`--story` or `--docs`. Quote globs (`--docs 'kb/*.md'`) so the shell leaves them
|
|
33
|
+
to gym.
|
|
14
34
|
|
|
15
35
|
## Subcommands
|
|
16
36
|
|
|
17
|
-
| Command
|
|
18
|
-
|
|
|
19
|
-
| `serve
|
|
20
|
-
| `build
|
|
21
|
-
| `cache ls\|clear`
|
|
22
|
-
| `
|
|
37
|
+
| Command | What it does |
|
|
38
|
+
| --------------------- | --------------------------------------------------------------- |
|
|
39
|
+
| `serve [spec...]` | Index everything, then serve. Handlers are written on first use |
|
|
40
|
+
| `build [spec...]` | Index everything and write every handler, then exit |
|
|
41
|
+
| `cache ls\|clear` | Handlers, bindings and indexes; `clear` keeps worlds |
|
|
42
|
+
| `world ls\|rm <name>` | List worlds, or delete one |
|
|
43
|
+
| `model [ref]` | Show or set the chat model; `--embedding <ref\|none\|clear>` |
|
|
23
44
|
|
|
24
45
|
```
|
|
25
46
|
zen gym serve openapi.yaml
|
|
26
|
-
zen gym serve
|
|
27
|
-
zen gym
|
|
28
|
-
zen gym
|
|
47
|
+
zen gym serve --schema specs/ --story world.md --docs kb/
|
|
48
|
+
zen gym serve specs/mail.yaml --story world.md --port 8787
|
|
49
|
+
zen gym serve specs/calendar.yaml --story world.md --port 8788 # same world as above
|
|
50
|
+
zen gym serve api.yaml --world demo --reset # a named world, emptied
|
|
51
|
+
zen gym build --schema 'api/*.yaml' --story world.md --docs kb/ --concurrency 8
|
|
52
|
+
zen gym world ls
|
|
29
53
|
```
|
|
30
54
|
|
|
31
|
-
`build` is the one to run in CI or before a demo: it pays for every
|
|
32
|
-
front and exits non-zero, with a table, if any could not be written.
|
|
55
|
+
`build` is the one to run in CI or before a demo: it pays for every handler up
|
|
56
|
+
front and exits non-zero, with a table, if any could not be written. Content is
|
|
57
|
+
still made lazily, on first read.
|
|
33
58
|
|
|
34
59
|
## Options
|
|
35
60
|
|
|
36
|
-
| Flag
|
|
37
|
-
|
|
|
38
|
-
| `--
|
|
39
|
-
| `--
|
|
40
|
-
| `--
|
|
41
|
-
| `--
|
|
42
|
-
| `--
|
|
43
|
-
| `--
|
|
44
|
-
| `--
|
|
45
|
-
| `--
|
|
46
|
-
| `--
|
|
47
|
-
| `--
|
|
48
|
-
| `--
|
|
49
|
-
| `--
|
|
50
|
-
| `--
|
|
61
|
+
| Flag | Default | Meaning |
|
|
62
|
+
| ----------------------- | ------------------- | -------------------------------------------------------- |
|
|
63
|
+
| `--schema <path>` | - | API documents, in addition to bare arguments |
|
|
64
|
+
| `--story <path>` | - | The state of the world |
|
|
65
|
+
| `--docs <path>` | - | Reference material |
|
|
66
|
+
| `--world <name\|file>` | one per story | Which world; a name is under `<cache>/worlds/` |
|
|
67
|
+
| `--reset` | - | Start from an empty world |
|
|
68
|
+
| `--model <ref>` | recommended | Which model writes handlers and content |
|
|
69
|
+
| `--embedding <on\|ref>` | off (wording) | Also search `--docs` by meaning; `on` = configured model |
|
|
70
|
+
| `--port <n>` | `8787` | Port to listen on |
|
|
71
|
+
| `--host <h>` | `127.0.0.1` | Anything else is reachable off-machine |
|
|
72
|
+
| `--cache <dir>` | `~/.zenera/neo/gym` | Handlers, worlds, indexes, reports |
|
|
73
|
+
| `--seed <n>` | - | Same request, same randomness |
|
|
74
|
+
| `--attempts <n>` | `5` | Failed tests per handler before giving up |
|
|
75
|
+
| `--concurrency <n>` | `4` | Handlers written at once |
|
|
76
|
+
| `--timeout <s>` | `30` | Seconds a handler may run, agent time aside |
|
|
77
|
+
| `--max-body <n>` | 1 MB | Largest request body accepted, in bytes |
|
|
78
|
+
| `--rebuild` | - | Ignore what is cached and write it again |
|
|
79
|
+
| `--no-cache` | - | Do not record what is written |
|
|
80
|
+
| `--quiet` | - | No narration |
|
|
51
81
|
|
|
52
82
|
Credentials come from the `zen` keyring - see [keys.md](keys.md).
|
|
53
|
-
|
|
54
|
-
|
|
83
|
+
Chat model: `--model`, `ZENERA_GYM_MODEL`, `zen gym model <ref>`, then the best
|
|
84
|
+
model the available keys support. It must call tools; for OpenAI reasoning
|
|
85
|
+
models use the Responses API, `openai/responses:<id>`. Embedding model: off by
|
|
86
|
+
default, so `--docs` are searched by wording (full-text). `--embedding <ref>`
|
|
87
|
+
searches by meaning too with that model; `--embedding on` takes
|
|
88
|
+
`ZENERA_GYM_EMBEDDING`, then `zen gym model --embedding <ref>`, then the first
|
|
89
|
+
provider with a key that offers one. Without the flag those settings do nothing.
|
|
55
90
|
|
|
56
91
|
## Serving
|
|
57
92
|
|
|
58
|
-
Binds the loopback address by default. On start it prints a table per document
|
|
59
|
-
|
|
60
|
-
a generator.
|
|
93
|
+
Binds the loopback address by default. On start it prints a table per document,
|
|
94
|
+
then the model, story, docs (and how they are searched) and the world file.
|
|
61
95
|
|
|
62
|
-
| Endpoint | Answers
|
|
63
|
-
| --------------- |
|
|
64
|
-
|
|
|
65
|
-
| `/__gym/
|
|
96
|
+
| Endpoint | Answers |
|
|
97
|
+
| --------------- | -------------------------------------------- |
|
|
98
|
+
| `/` | Contents page, with a Run form per operation |
|
|
99
|
+
| `/__gym/routes` | Every route it will serve |
|
|
100
|
+
| `/__gym/health` | Whether it is up |
|
|
66
101
|
|
|
67
102
|
Response headers:
|
|
68
103
|
|
|
69
104
|
| Header | Meaning |
|
|
70
105
|
| ----------------- | ----------------------------------------------------- |
|
|
71
106
|
| `x-gym-operation` | The `operationId` that answered |
|
|
72
|
-
| `x-gym-cache` | `hit` or `
|
|
107
|
+
| `x-gym-cache` | `hit`, `miss` or `regenerated` - the handler's origin |
|
|
73
108
|
|
|
74
109
|
Gym provides simulation, not task scoring, rewards, or a training loop.
|
|
75
110
|
|
|
76
111
|
Incoming headers are filtered: `authorization`, `cookie` and anything matching
|
|
77
|
-
`key|token|secret|password|credential` never reach a
|
|
78
|
-
|
|
79
|
-
`--seed` makes each request's seed a hash of the seed, the operation and the
|
|
80
|
-
parameters, so the same request answers identically across restarts - which is
|
|
81
|
-
what makes a mock usable in a test.
|
|
112
|
+
`key|token|secret|password|credential` never reach a handler.
|
|
82
113
|
|
|
83
114
|
## What "correct" means here
|
|
84
115
|
|
|
85
|
-
A
|
|
116
|
+
A handler is judged by `test_handler` on synthetic probes, in a throwaway copy
|
|
117
|
+
of the world with schema-sampled content: the body validates against the
|
|
86
118
|
response schema, **and** it obeys the **echo rule** - a value given in the path
|
|
87
|
-
comes back in the answer
|
|
88
|
-
|
|
89
|
-
|
|
119
|
+
comes back in the answer (`GET /users/12324` must return `user_id: 12324`).
|
|
120
|
+
Paged operations are walked: the cursor must advance and end. And every record
|
|
121
|
+
type the handler touches must live where earlier handlers put it.
|
|
90
122
|
|
|
91
|
-
|
|
92
|
-
and `?cursor` are controls, and their names collide with unrelated response
|
|
93
|
-
fields.
|
|
123
|
+
## Bindings: where each type lives
|
|
94
124
|
|
|
95
|
-
|
|
125
|
+
Handlers name records by schema type (`ctx.lookup('Message', id)`). The first
|
|
126
|
+
handler to use a type binds it to a collection and id field; later handlers are
|
|
127
|
+
told the binding and held to it, so every operation on a resource reads the same
|
|
128
|
+
records. Bindings are add-only and machine-wide, keyed by the documents' types;
|
|
129
|
+
`cache clear` forgets them.
|
|
96
130
|
|
|
97
|
-
## The cache
|
|
131
|
+
## The cache, the world, the reports
|
|
98
132
|
|
|
99
|
-
|
|
100
|
-
keyed by the operation's shape
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
a hopeless operation is not re-asked on every request; a _transient_ failure - a
|
|
104
|
-
429, a dropped socket - is not, because it is about this minute rather than this
|
|
105
|
-
operation.
|
|
133
|
+
Handlers live in the machine's shared cache, `~/.zenera/neo/cache/gym-handler/`,
|
|
134
|
+
keyed by the operation's shape (descriptions and examples excluded) - not by the
|
|
135
|
+
story, since a handler holds no content. A cached handler whose bindings no
|
|
136
|
+
longer hold is rebuilt. Two processes needing the same handler build it once.
|
|
106
137
|
|
|
107
|
-
|
|
108
|
-
|
|
138
|
+
Worlds live in `<cache>/worlds/`. With a story and no `--world`, the world is
|
|
139
|
+
named after the story's content, so editing the story starts a new world (gym
|
|
140
|
+
says so). `cache clear` never touches worlds; `world rm` and `serve --reset` do.
|
|
109
141
|
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
go together: the container's name is a hash of its configuration, so deleting
|
|
113
|
-
the workspace alone would leave a stopped container bind-mounted onto a
|
|
114
|
-
directory that no longer exists, and every generator would fail with
|
|
115
|
-
`python3: can't open file '/workspace/generators/…/gen.py'`.
|
|
142
|
+
The docs index lives in `<cache>/indexes/`, keyed by the docs' content and the
|
|
143
|
+
embedding model; a restart reuses it.
|
|
116
144
|
|
|
117
|
-
|
|
118
|
-
|
|
145
|
+
Every agent run leaves an HTML report in `<cache>/reports/`; failed builds
|
|
146
|
+
leave a markdown report in `<cache>/builds/`.
|
|
119
147
|
|
|
120
148
|
## Documents it accepts
|
|
121
149
|
|
|
122
150
|
Swagger 2 and OpenAPI 3.0/3.1, JSON or YAML, `$ref`s resolved. Several documents
|
|
123
|
-
can be served at once
|
|
124
|
-
|
|
125
|
-
|
|
126
|
-
|
|
151
|
+
can be served at once, as long as no two define the same route (two versions of
|
|
152
|
+
one API: serve them from two processes with the same `--world`). OpenAPI 3.0
|
|
153
|
+
constructs are translated to JSON Schema 2020-12 on the way in (`nullable`,
|
|
154
|
+
boolean `exclusiveMinimum`, Draft-4 array `items`), and a `pattern` written as a
|
|
155
|
+
JavaScript regex literal (`/^[a-z]+$/`) is unwrapped.
|
|
@@ -32,6 +32,16 @@ dereference: having seen the shape and spotted the loop, you open the three
|
|
|
32
32
|
nodes that explain it, whole and untruncated. The index is cheap and you only
|
|
33
33
|
pay for what you open.
|
|
34
34
|
|
|
35
|
+
For a whole-run audit, follow **zen-analyze-run**: reuse the graph, begin with
|
|
36
|
+
the outcome, batch selected evidence nodes, and expand backwards only for a
|
|
37
|
+
specific unresolved criterion or anomaly. Labels locate evidence; exact
|
|
38
|
+
arguments, returned facts and success claims require the relevant payload.
|
|
39
|
+
Stop when the evidence is sufficient, not after opening every node.
|
|
40
|
+
Start with supporting or contradicting results; select decision nodes only
|
|
41
|
+
after identifying a remaining evidence gap or material attribution question.
|
|
42
|
+
Keep each retrieved node part and its output location, and search that copy
|
|
43
|
+
for all quotations rather than fetching it once per phrase.
|
|
44
|
+
|
|
35
45
|
`ask` is the last resort, not the first move: it spends a model call to ask the
|
|
36
46
|
run's own model why it did what it did. Open the node first - most questions are
|
|
37
47
|
answered by reading what it was given.
|
|
@@ -278,6 +288,11 @@ zen inspect node n11 --part thinking --part text --dir <run dir>
|
|
|
278
288
|
zen inspect node n11 --full --dir <run dir>
|
|
279
289
|
```
|
|
280
290
|
|
|
291
|
+
Those are explicit deep-inspection options, not whole-run audit defaults.
|
|
292
|
+
Prefer `--part call` for LLM tool arguments and `--part text` for its public
|
|
293
|
+
answer. Open `thinking` only when unresolved attribution would change a
|
|
294
|
+
recommendation; self-explanations do not prove causation.
|
|
295
|
+
|
|
281
296
|
An `llm_call` carries two more parts read out of its request, held back the
|
|
282
297
|
same way: `tools`, the tool names that call was offered, one per line, and
|
|
283
298
|
`messages`, the conversation it saw, one clipped line per message with its
|
|
@@ -26,6 +26,12 @@ zen inspect ask <llm-node-id> --question-file <question file> --dir <run-dir>
|
|
|
26
26
|
Each non-interactive call is a **fresh replay**. It does not remember your
|
|
27
27
|
previous question. A follow-up must restate what it builds on.
|
|
28
28
|
|
|
29
|
+
For a whole-run audit, **zen-analyze-run** owns the replay budget: default
|
|
30
|
+
zero, at most two invocations including retries and second opinions. Its
|
|
31
|
+
budget and uncertainty gate take precedence over the retry suggestions below.
|
|
32
|
+
Do not replay a healthy run or ask about a cause already established by
|
|
33
|
+
recorded evidence.
|
|
34
|
+
|
|
29
35
|
## 1. Rule out the cheap causes first
|
|
30
36
|
|
|
31
37
|
A "why didn't you" question is only about instructions if the model could have
|
|
@@ -242,18 +248,21 @@ only a finding once the sentence is confirmed.
|
|
|
242
248
|
```sh
|
|
243
249
|
zen inspect node n9 --part request --dir <run-dir> | grep -F 'Do not fork a sequence'
|
|
244
250
|
```
|
|
251
|
+
Reuse a request already retrieved; fetch it once and check all quotes
|
|
252
|
+
against that copy. A match in a project file alone does not prove delivery.
|
|
245
253
|
A quote that is not there is invented - discard the answer, not just the
|
|
246
|
-
quote.
|
|
254
|
+
quote. Retry only within the caller's budget; otherwise report that
|
|
255
|
+
attribution remains unresolved.
|
|
247
256
|
2. **Find every copy.** The blocker often exists twice - once in a house rule,
|
|
248
257
|
once in a skill with a softer tail. Grep the whole request for a distinctive
|
|
249
258
|
phrase of it, then grep the project's `agents/` tree for the file to edit.
|
|
250
259
|
3. **Check it is the project's file.** `fork-instructions.md`,
|
|
251
260
|
`memory-instructions.md`, `tools-instructions.md` are zen's own copies; load
|
|
252
261
|
**zen-instructions** before changing where that rule lives.
|
|
253
|
-
4. **Second opinion when
|
|
254
|
-
|
|
255
|
-
|
|
256
|
-
question file.
|
|
262
|
+
4. **Second opinion only when justified.** A thin answer or `no instruction -
|
|
263
|
+
my own default` does not itself justify more replay. In a whole-run audit,
|
|
264
|
+
use a second opinion only after an invented quote, and within the two-call
|
|
265
|
+
total budget: `--model <ref>`, the identical question file.
|
|
257
266
|
5. **Reproduce.** After the edit, rerun the case and check the graph: the
|
|
258
267
|
`tools` header row shows `fork x1` or `memory_search x1` where it did not
|
|
259
268
|
before. The answer predicted a fix; the graph confirms it.
|
|
@@ -36,8 +36,12 @@ NOISE='^(and/or|he/she|his/her|input/output|read/write|w/o|n/a|N/A|24/7|km/h)$|^
|
|
|
36
36
|
# A url, stripped before tokenising rather than filtered after it — the token
|
|
37
37
|
# regex reads `https://acme.dev/docs` as `//acme.dev` *and* `/docs`, and the
|
|
38
38
|
# second half is indistinguishable from a real absolute path once it is alone.
|
|
39
|
+
#
|
|
40
|
+
# A meta agent command, `zen meta run /spec-edit`, goes the same way: its
|
|
41
|
+
# `/<name>` is a stored prompt, not a file the running agent is told to open.
|
|
39
42
|
strip_urls() {
|
|
40
|
-
sed -E 's#[a-zA-Z][a-zA-Z0-9+.-]*://[^][ )"'"'"'`>]*##g'
|
|
43
|
+
sed -E -e 's#[a-zA-Z][a-zA-Z0-9+.-]*://[^][ )"'"'"'`>]*##g' \
|
|
44
|
+
-e 's#(zen meta run( [A-Za-z0-9_.-]+)?) /[A-Za-z0-9_-]+#\1#g' "$1"
|
|
41
45
|
}
|
|
42
46
|
|
|
43
47
|
# The three trees §2.5 names, prose only: a skill's own script is code the
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: zen-spec-sync
|
|
3
|
-
description: Running `/spec-sync-project` as an incremental pass - the committed `.spec-sync` baseline of what the last pass applied, how to scope a pass from the specification and feedback diffs and from what moved in the project itself, the five checks a narrow pass may never skip, which skills a pass must load before editing (`zen-instructions` for any house rule it touches), the iteration history format, and why the baseline is written last. Load before every `/spec-sync-project`, including the first one on a project that has no baseline yet.
|
|
3
|
+
description: Running `/spec-sync-project` as an incremental pass - the committed `.spec-sync` baseline of what the last pass applied, how to scope a pass from the specification and feedback diffs and from what moved in the project itself, which input wins when they disagree, the five checks a narrow pass may never skip, which skills a pass must load before editing (`zen-instructions` for any house rule it touches), the iteration history format, and why the baseline is written last. Load before every `/spec-sync-project`, including the first one on a project that has no baseline yet.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# Syncing a project with its specification, one change at a time
|
|
@@ -103,9 +103,64 @@ editing anything, and report it in the chat as the pass's scope.
|
|
|
103
103
|
covers it, and you say which line, or it does not, and it is an **extra**
|
|
104
104
|
reported under `➕`.
|
|
105
105
|
|
|
106
|
+
## When the inputs disagree
|
|
107
|
+
|
|
108
|
+
Two inputs can ask for different things - a ticked answer and a later edit to
|
|
109
|
+
the same specification line, say. Decide by this order, highest first, and do
|
|
110
|
+
not weigh them again:
|
|
111
|
+
|
|
112
|
+
1. **The user's message that started this pass**, where it says more than the
|
|
113
|
+
command name. It is the newest and most direct statement of intent there is.
|
|
114
|
+
2. **`SPECIFICATION.md` as it stands now.** An edit to the specification is
|
|
115
|
+
made on purpose and after the questions were written, so it outranks them.
|
|
116
|
+
3. **An answer ticked in `SPECIFICATION-FEEDBACK.md`** and not yet folded in.
|
|
117
|
+
4. **What the last pass left open.**
|
|
118
|
+
|
|
119
|
+
A ticked answer that the current specification text contradicts was
|
|
120
|
+
**superseded**, not ignored: do not fold its text back in over the newer line.
|
|
121
|
+
Strike the question with one line naming the specification line that replaced
|
|
122
|
+
it, and say in the chat that you did.
|
|
123
|
+
|
|
124
|
+
Facts outrank all four. `zen --version` decides the sandbox pin (below); a
|
|
125
|
+
specification line asking for something impossible is a question, not an order.
|
|
126
|
+
Where the order above does not decide, build what the higher-ranked input asks
|
|
127
|
+
for, write **one** question in `SPECIFICATION-FEEDBACK.md`, and carry on.
|
|
128
|
+
|
|
129
|
+
### Do not reconstruct intent
|
|
130
|
+
|
|
131
|
+
The diffs say what changed. The order above says what wins. A feedback question
|
|
132
|
+
covers whatever is left. Do not use anything else to work out _why_ somebody
|
|
133
|
+
changed something: no session history or chat transcripts, no file timestamps,
|
|
134
|
+
no `git log` or `git blame`, no older history entries beyond the one `applied:`
|
|
135
|
+
names. If a pass catches itself guessing at what the human meant, that guess is
|
|
136
|
+
the text of a question, and the pass moves on.
|
|
137
|
+
|
|
138
|
+
### The `zen` version in the specification
|
|
139
|
+
|
|
140
|
+
The `@zenera/cli` and `@zenera/rag` pin in `sandbox/Dockerfile` always follows
|
|
141
|
+
`zen --version` - `zen check` warns on any other number, older or newer. Nothing
|
|
142
|
+
outranks that, not a specification line and not the user's message: the image
|
|
143
|
+
cannot hold a `zen` other than the one building it. If a version was asked for
|
|
144
|
+
that is not the one in hand, say so in the chat - `zen` has to be upgraded on the
|
|
145
|
+
host first.
|
|
146
|
+
|
|
147
|
+
When `SPECIFICATION.md` names an exact version other than `zen --version`, pin
|
|
148
|
+
the Dockerfile to `zen --version` and keep **one** `✏️` question open for that
|
|
149
|
+
line. If one is already open, update it instead of adding another. Offer these
|
|
150
|
+
answers:
|
|
151
|
+
|
|
152
|
+
- State the pin without a number - "pinned to the `zen` version that builds the
|
|
153
|
+
image" - so the next upgrade does not raise the question again
|
|
154
|
+
_(recommended)_.
|
|
155
|
+
- Replace the number with the one `zen --version` reports.
|
|
156
|
+
- Keep the number, upgrade `zen` on the host to it, and run the pass again.
|
|
157
|
+
|
|
158
|
+
That is the whole of the work. A version mismatch is not a reason to look for
|
|
159
|
+
anything else.
|
|
160
|
+
|
|
106
161
|
## The five checks a narrow pass may never skip
|
|
107
162
|
|
|
108
|
-
However small the diff:
|
|
163
|
+
However small the diff - with the one narrowing for a spec-only pass below:
|
|
109
164
|
|
|
110
165
|
1. **`zen check` passes.** Run it before the first edit and again after the
|
|
111
166
|
last.
|
|
@@ -131,6 +186,28 @@ However small the diff:
|
|
|
131
186
|
it, the history entry claims it, and the baseline records it as applied.
|
|
132
187
|
Specification-driven rules go in a topic file of the project's own beside it.
|
|
133
188
|
|
|
189
|
+
### The spec-only pass
|
|
190
|
+
|
|
191
|
+
A pass qualifies when **all** of the following hold:
|
|
192
|
+
|
|
193
|
+
- the implementation diff (input 4) is empty
|
|
194
|
+
- the pass edits nothing except `SPECIFICATION.md`, `SPECIFICATION-FEEDBACK.md`
|
|
195
|
+
and the `@zenera/*` pin in `sandbox/Dockerfile`
|
|
196
|
+
- no changed specification hunk names an agent, tool, model, embedding, skill,
|
|
197
|
+
house rule, handoff, memory, index, asset or setup step
|
|
198
|
+
|
|
199
|
+
A pass like that changes nothing an agent reads, so it has no capability
|
|
200
|
+
obligation to re-check. Checks 4 and 5 drop out: load no capability skill and no
|
|
201
|
+
`zen-instructions`. `zen check` still runs before and after, and it still
|
|
202
|
+
reports `rules.stale`. Check 2 shrinks to `scripts/_setup.sh --check`, which
|
|
203
|
+
must report every step `skipped`. If it reports anything else, run
|
|
204
|
+
`scripts/_setup.sh` in full as written. Check 3 shrinks to the §9
|
|
205
|
+
**Specification** group and the groups covering any file the pass edited.
|
|
206
|
+
|
|
207
|
+
Decide this before loading anything, and say it in the chat - "spec-only pass:"
|
|
208
|
+
followed by the reason. If any edit turns out to reach further, the pass is no
|
|
209
|
+
longer spec-only: run all five checks.
|
|
210
|
+
|
|
134
211
|
A narrow diff narrows reading and editing. It does not narrow verification.
|
|
135
212
|
|
|
136
213
|
## What else an incremental pass still owes
|
|
@@ -26,6 +26,20 @@ Search before starting work that costs more than one cheap read or call:
|
|
|
26
26
|
Do not repeat the same search in different words. Search again only when the
|
|
27
27
|
question has changed.
|
|
28
28
|
|
|
29
|
+
When a request involves several distinct subjects, search for all of them in
|
|
30
|
+
parallel: send one `memory_search` per subject in the same turn rather than one
|
|
31
|
+
after another. Likewise, load every node you need in the same turn. Parallel
|
|
32
|
+
searches must ask different questions, not rephrase one.
|
|
33
|
+
|
|
34
|
+
### Call memory tools silently
|
|
35
|
+
|
|
36
|
+
You MUST NOT write any text before a `memory_*` call. Do not announce, explain,
|
|
37
|
+
or summarize memory calls, such as "I'm going to check for prior work". The
|
|
38
|
+
tool call is shown to the user on its own. This overrides the general rule to
|
|
39
|
+
say what you are about to do before tool calls: when a turn contains only
|
|
40
|
+
`memory_*` calls, write nothing; when it mixes them with other tools, describe
|
|
41
|
+
only the other calls.
|
|
42
|
+
|
|
29
43
|
### Choose the retrieval tool
|
|
30
44
|
|
|
31
45
|
| Need | Tool |
|
|
@@ -17,3 +17,63 @@ Anything under `/assets` is reference material: read it, search it, and do not
|
|
|
17
17
|
try to change it.
|
|
18
18
|
|
|
19
19
|
Say what you changed.
|
|
20
|
+
|
|
21
|
+
<!-- ===== BEGIN: unconfigured-agent disclaimer (delete this block once the agent is configured) ===== -->
|
|
22
|
+
|
|
23
|
+
## This agent is not configured yet
|
|
24
|
+
|
|
25
|
+
This agent has not been set up for any specific task yet. It only has the
|
|
26
|
+
generic defaults above, so it is not expected to do anything particularly
|
|
27
|
+
useful on its own.
|
|
28
|
+
|
|
29
|
+
When the user greets you ("hi", "hello"), asks what you can do, asks who you
|
|
30
|
+
are, or asks how to get started, tell them plainly:
|
|
31
|
+
|
|
32
|
+
- This agent is not configured yet to do anything useful.
|
|
33
|
+
- To teach it specific tasks, they should use the **Zenera Meta Agent**,
|
|
34
|
+
which can configure this agent's prompts, tools, knowledge and workflows.
|
|
35
|
+
It ships with the `zen` CLI:
|
|
36
|
+
- What it is and how it works:
|
|
37
|
+
https://github.com/zenera-ai/ZeneraNeo#what-is-the-meta-agent
|
|
38
|
+
- The CLI and its commands:
|
|
39
|
+
https://github.com/zenera-ai/ZeneraNeo/tree/main/packages/cli
|
|
40
|
+
- The project home: https://zenera.ai
|
|
41
|
+
|
|
42
|
+
Then give them these steps to get started. The commands run in a terminal on
|
|
43
|
+
their machine, from the project directory, not here:
|
|
44
|
+
|
|
45
|
+
1. Pick the model the meta agent uses (once per machine):
|
|
46
|
+
`zen meta model --pick`
|
|
47
|
+
2. Describe what this agent should do in `SPECIFICATION.md`: its purpose,
|
|
48
|
+
models, agents, tools, knowledge and memory. Edit the file by hand, or have
|
|
49
|
+
the meta agent write it from a plain request:
|
|
50
|
+
`zen meta run /spec-edit "<what to add, change or remove>"`
|
|
51
|
+
3. Have the meta agent build the system from the specification:
|
|
52
|
+
`zen meta run /spec-sync-project`
|
|
53
|
+
4. If the meta agent has questions, it writes them to
|
|
54
|
+
`SPECIFICATION-FEEDBACK.md`. Answer them there, then apply the answers:
|
|
55
|
+
`zen meta run /spec-apply-feedback`
|
|
56
|
+
5. Validate the project and try it: `zen check`, then `zen run "<request>"`.
|
|
57
|
+
Review a run with `zen inspect`.
|
|
58
|
+
|
|
59
|
+
To find out more, `--help` works on every command and subcommand:
|
|
60
|
+
|
|
61
|
+
- `zen meta --help` lists everything the meta agent can do: `run`,
|
|
62
|
+
`prompts`, `resume`, `model`, `dataset` and `finetune`, with examples.
|
|
63
|
+
- `zen meta run --help` lists the options for a run and the stored prompts,
|
|
64
|
+
the `/<name>` commands used above.
|
|
65
|
+
`zen meta prompts` lists the stored prompts on their own.
|
|
66
|
+
- `zen meta dataset --help` and `zen meta finetune --help` cover building an
|
|
67
|
+
evaluation dataset and tuning the project against it.
|
|
68
|
+
- `zen meta run "<question>"` asks the meta agent anything about the project,
|
|
69
|
+
for example `zen meta run "what does this project do?"`.
|
|
70
|
+
|
|
71
|
+
For teams that need more, mention **ZeneraLab**, Zenera's enterprise-grade
|
|
72
|
+
platform (https://zenera.ai). It has all of this built into a UI, where users
|
|
73
|
+
can build enterprise-grade agentic solutions, integrate them with any legacy
|
|
74
|
+
system, and train, fine-tune, optimize, test and monitor their agents.
|
|
75
|
+
|
|
76
|
+
Keep that answer short and friendly. You can still help with simple requests
|
|
77
|
+
in the workspace if asked directly.
|
|
78
|
+
|
|
79
|
+
<!-- ===== END: unconfigured-agent disclaimer ===== -->
|