vinta-ai-workflows 0.7.0-alpha8 → 0.7.0-alpha9
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/CHANGELOG.md +25 -0
- package/package.json +1 -1
- package/schemas/workflow.v1.schema.json +135 -0
package/CHANGELOG.md
CHANGED
|
@@ -7,6 +7,7 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
7
7
|
|
|
8
8
|
## [0.7.0] — YYYY-MM-DD
|
|
9
9
|
|
|
10
|
+
<!-- pre-release: 0.7.0-alpha9 on 2026-09-14 -->
|
|
10
11
|
<!-- pre-release: 0.7.0-alpha8 on 2026-09-14 -->
|
|
11
12
|
<!-- pre-release: 0.7.0-alpha7 on 2026-09-14 -->
|
|
12
13
|
<!-- pre-release: 0.7.0-alpha6 on 2026-09-13 -->
|
|
@@ -18,6 +19,30 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
|
|
|
18
19
|
|
|
19
20
|
### Added
|
|
20
21
|
|
|
22
|
+
- **A project declares what makes a lane runnable.** `project.env_files` copies
|
|
23
|
+
ignored configuration into each worktree, `project.setup_cmd` runs an
|
|
24
|
+
idempotent setup hook on provisioning and recycle, and the fixed
|
|
25
|
+
`project.commands` vocabulary tells implementers, reviewers and fixers the
|
|
26
|
+
project's real lint, typecheck, test and migration entry points.
|
|
27
|
+
|
|
28
|
+
- **Compose-backed lanes are isolated past `COMPOSE_PROJECT_NAME`.** The daemon
|
|
29
|
+
now generates an out-of-tree Compose override per lane, strips fixed host
|
|
30
|
+
ports, re-pins fixed and external volumes, and carries the complete lane
|
|
31
|
+
environment into agent and takeover processes as well as gates. Explicitly
|
|
32
|
+
published services receive probed per-lane ports recorded in the teardown
|
|
33
|
+
summary.
|
|
34
|
+
|
|
35
|
+
- **Shared services get one namespace per lane.** `project.services` models a
|
|
36
|
+
fixed index or lane-derived name inside one Redis, RabbitMQ, object-storage,
|
|
37
|
+
or similar server, with project-owned create/reset commands and capacity
|
|
38
|
+
validation before provisioning creates templates or worktrees.
|
|
39
|
+
|
|
40
|
+
- **Agents can take the semaphore a workflow declares.**
|
|
41
|
+
`vinta-ai-maestro with <resource> -- <cmd>` waits on the run's existing
|
|
42
|
+
`ResourcePools`, runs the heavy inner-loop command, and releases on exit.
|
|
43
|
+
Renewable leases expire when their client disappears, are visible in the
|
|
44
|
+
live journal, and are surfaced in implementer, reviewer and fixer prompts.
|
|
45
|
+
|
|
21
46
|
- **A failed phase retries itself, and then asks.** `--on-failure` defaults to
|
|
22
47
|
`retry`: one cold re-attempt (`--retries <n>`, 0–5), and then the node parks
|
|
23
48
|
on a question — retry, retry with another member of the crew, or stop. The
|
package/package.json
CHANGED
|
@@ -191,6 +191,141 @@
|
|
|
191
191
|
}
|
|
192
192
|
},
|
|
193
193
|
"additionalProperties": false
|
|
194
|
+
},
|
|
195
|
+
"env_files": {
|
|
196
|
+
"default": [],
|
|
197
|
+
"description": "Repo-relative ignored files every lane needs its own COPY of — `.env`, `.env.docker`, `.envrc`. Copied, never symlinked: lane provisioning appends to them (a connection string, a compose override path), and a symlink would write those lane-specific lines back into the main checkout. A declared file that is missing fails provisioning rather than producing a lane whose stack cannot boot.",
|
|
198
|
+
"type": "array",
|
|
199
|
+
"items": {
|
|
200
|
+
"type": "string",
|
|
201
|
+
"minLength": 1
|
|
202
|
+
}
|
|
203
|
+
},
|
|
204
|
+
"commands": {
|
|
205
|
+
"default": {},
|
|
206
|
+
"type": "object",
|
|
207
|
+
"properties": {
|
|
208
|
+
"lint": {
|
|
209
|
+
"type": "string",
|
|
210
|
+
"minLength": 1
|
|
211
|
+
},
|
|
212
|
+
"typecheck": {
|
|
213
|
+
"type": "string",
|
|
214
|
+
"minLength": 1
|
|
215
|
+
},
|
|
216
|
+
"test": {
|
|
217
|
+
"description": "The whole suite.",
|
|
218
|
+
"type": "string",
|
|
219
|
+
"minLength": 1
|
|
220
|
+
},
|
|
221
|
+
"test_one": {
|
|
222
|
+
"description": "A single test or a subtree. The agent appends the target, so end it accordingly.",
|
|
223
|
+
"type": "string",
|
|
224
|
+
"minLength": 1
|
|
225
|
+
},
|
|
226
|
+
"migrate": {
|
|
227
|
+
"type": "string",
|
|
228
|
+
"minLength": 1
|
|
229
|
+
}
|
|
230
|
+
},
|
|
231
|
+
"additionalProperties": false,
|
|
232
|
+
"description": "The project’s own command lines, handed to every agent verbatim. A fixed vocabulary rather than free-form, because the prompt has to be able to say which one step 3 of the working instructions means. Declaring these is how an agent stops guessing: a project whose suite only runs inside a container, or only against a lane-specific database, has no way of telling one otherwise, and `pytest` is a plausible guess that is wrong in exactly that project."
|
|
233
|
+
},
|
|
234
|
+
"services": {
|
|
235
|
+
"default": {},
|
|
236
|
+
"description": "Shared servers each lane gets its own namespace inside, by id. One postgres, one redis, one rabbit on the machine, with a database / db index / vhost per lane — which is the difference between six lanes being viable on a laptop and not. The alternative a project falls into without this is booting a server per lane, or sharing one with no isolation at all.",
|
|
237
|
+
"type": "object",
|
|
238
|
+
"propertyNames": {
|
|
239
|
+
"type": "string",
|
|
240
|
+
"minLength": 1,
|
|
241
|
+
"pattern": "^[a-z0-9][a-z0-9-]*$"
|
|
242
|
+
},
|
|
243
|
+
"additionalProperties": {
|
|
244
|
+
"type": "object",
|
|
245
|
+
"properties": {
|
|
246
|
+
"namespace": {
|
|
247
|
+
"type": "string",
|
|
248
|
+
"enum": [
|
|
249
|
+
"index",
|
|
250
|
+
"name"
|
|
251
|
+
],
|
|
252
|
+
"description": "How this lane’s namespace inside the shared server is derived. `index` is a small integer, for a server with a fixed number of slots — redis’s sixteen databases are the case it exists for. `name` is a token derived from the lane, for a server that names things freely: a vhost, a bucket prefix, a schema."
|
|
253
|
+
},
|
|
254
|
+
"url": {
|
|
255
|
+
"description": "The shared server, without the per-lane segment — `redis://localhost:6379`. Omit it where the namespace *is* the value: an object-storage prefix has no URL to hang off, and the variable then carries the bare token.",
|
|
256
|
+
"type": "string",
|
|
257
|
+
"minLength": 1
|
|
258
|
+
},
|
|
259
|
+
"url_var": {
|
|
260
|
+
"type": "string",
|
|
261
|
+
"minLength": 1,
|
|
262
|
+
"description": "Env var the lane reads this service’s address from."
|
|
263
|
+
},
|
|
264
|
+
"capacity": {
|
|
265
|
+
"default": 16,
|
|
266
|
+
"description": "How many distinct namespaces the server has. Only meaningful for `index`, where a pool larger than this is refused before anything is created — two lanes on one redis database is the bug this exists to prevent, and reaching it by arithmetic is no better than reaching it by neglect.",
|
|
267
|
+
"type": "integer",
|
|
268
|
+
"minimum": 1,
|
|
269
|
+
"maximum": 9007199254740991
|
|
270
|
+
},
|
|
271
|
+
"create_cmd": {
|
|
272
|
+
"description": "Run once per lane, in the lane. `{namespace}`, `{url}` and `{lane}` are substituted. Declaring a vhost is a `rabbitmqadmin` invocation this package has no business knowing; a project that needs none declares none.",
|
|
273
|
+
"type": "string",
|
|
274
|
+
"minLength": 1
|
|
275
|
+
},
|
|
276
|
+
"reset_cmd": {
|
|
277
|
+
"description": "Empties this lane’s namespace when the lane is handed to the next phase. Same substitutions. A service without one keeps whatever the last phase left in it, which for a cache is usually right and for a queue usually is not — declaring this is how a project says which of those it has.",
|
|
278
|
+
"type": "string",
|
|
279
|
+
"minLength": 1
|
|
280
|
+
}
|
|
281
|
+
},
|
|
282
|
+
"required": [
|
|
283
|
+
"namespace",
|
|
284
|
+
"url_var"
|
|
285
|
+
],
|
|
286
|
+
"additionalProperties": false,
|
|
287
|
+
"description": "A shared server each lane gets its own namespace inside."
|
|
288
|
+
}
|
|
289
|
+
},
|
|
290
|
+
"compose": {
|
|
291
|
+
"default": {
|
|
292
|
+
"enabled": true,
|
|
293
|
+
"publish": [],
|
|
294
|
+
"shared_volumes": []
|
|
295
|
+
},
|
|
296
|
+
"type": "object",
|
|
297
|
+
"properties": {
|
|
298
|
+
"enabled": {
|
|
299
|
+
"default": true,
|
|
300
|
+
"description": "Whether lane provisioning generates a compose override. On by default, and it does nothing at all in a project with no compose file. Where there is one and docker cannot answer, provisioning fails rather than quietly producing lanes that share a data volume — set this to false to say that is genuinely what you want.",
|
|
301
|
+
"type": "boolean"
|
|
302
|
+
},
|
|
303
|
+
"publish": {
|
|
304
|
+
"default": [],
|
|
305
|
+
"description": "Services that must keep a reachable host port, republished on one this lane was granted instead of the one the project pinned. Empty is the default and is usually right outright: where the project’s own test command runs inside compose, services reach each other by container DNS on the lane’s own network and a published port buys nothing but a collision. The granted port reaches the lane as `LANE_PORT_<SERVICE>_<CONTAINER_PORT>`.",
|
|
306
|
+
"type": "array",
|
|
307
|
+
"items": {
|
|
308
|
+
"type": "string",
|
|
309
|
+
"minLength": 1
|
|
310
|
+
}
|
|
311
|
+
},
|
|
312
|
+
"shared_volumes": {
|
|
313
|
+
"default": [],
|
|
314
|
+
"description": "Volume keys that leak past the project name and are to be left leaking. The escape hatch for the one decision this cannot make for you: re-pinning a shared dependency volume is correct, and it costs every lane the install that sharing it was avoiding. A read-only cache with no dependency churn in the plan is safe here. A data volume never is — that is two servers on one data directory, which is the bug this exists to prevent.",
|
|
315
|
+
"type": "array",
|
|
316
|
+
"items": {
|
|
317
|
+
"type": "string",
|
|
318
|
+
"minLength": 1
|
|
319
|
+
}
|
|
320
|
+
}
|
|
321
|
+
},
|
|
322
|
+
"additionalProperties": false,
|
|
323
|
+
"description": "How a lane’s compose stack is isolated past `COMPOSE_PROJECT_NAME`."
|
|
324
|
+
},
|
|
325
|
+
"setup_cmd": {
|
|
326
|
+
"description": "The project’s own lane-setup command, run inside each freshly provisioned lane with that lane’s environment applied. The escape hatch for whatever a project needs that no field here describes. It MUST be idempotent: it runs again every time the lane is recycled for another phase.",
|
|
327
|
+
"type": "string",
|
|
328
|
+
"minLength": 1
|
|
194
329
|
}
|
|
195
330
|
},
|
|
196
331
|
"required": [
|