vinta-ai-workflows 0.7.0-alpha35 → 0.7.0-alpha37

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 CHANGED
@@ -7,6 +7,8 @@ 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-alpha37 on 2026-10-20 -->
11
+ <!-- pre-release: 0.7.0-alpha36 on 2026-10-18 -->
10
12
  <!-- pre-release: 0.7.0-alpha35 on 2026-10-16 -->
11
13
  <!-- pre-release: 0.7.0-alpha34 on 2026-10-16 -->
12
14
  <!-- pre-release: 0.7.0-alpha33 on 2026-10-16 -->
@@ -35,6 +37,215 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
35
37
 
36
38
  ### Added
37
39
 
40
+ - **`vinta-ai-maestro`: `post_merge`.** A workflow (or `maestro.post_merge`)
41
+ may declare a command that runs in the integration worktree after git
42
+ merges a branch by itself, with `{files}` set to the files both sides
43
+ changed (for example `py_compile` plus `ruff check --fix` and
44
+ `ruff format`). Its changes are committed on top of the merge. If it fails,
45
+ the merge stays as git made it and the merged tree's gates judge it. Each
46
+ run is journalled as `post_merge_result`.
47
+ - **`vinta-ai-maestro`: `ci_only` records CI checks deliberately left to
48
+ CI.** It lives in a plan or in `maestro.ci_only` in
49
+ `.vinta-ai-workflows.yaml`. Each entry is a CI command with the reason no
50
+ gate runs it. `doctor`'s CI-coverage check stops warning about those
51
+ commands and counts them as decisions.
52
+ - **`vinta-ai-maestro`: `queue_timeout_s`, and the pool queue in `status`.**
53
+ A gate's `timeout_s` counts only its command's runtime, and a regression
54
+ test now pins that down. The optional `queue_timeout_s` bounds the wait
55
+ for the gate's pools: a gate that waits too long fails with how long it
56
+ waited and who held the pool. `status` shows each pool's queue in order,
57
+ for example `test-suite: p3b (holds 4m) → p5b (waits 22m) → p5c (waits 3m)`.
58
+ - **`vinta-ai-maestro`: a gate can run differently in a lane with no scope
59
+ cache.** A command gate may declare `scope_cache` (for example
60
+ `apps/api/.testmondata`) and `cold_cmd`. When a cache file is missing, the
61
+ phase gate runs `cold_cmd` (default `cmd`) instead of a scoped form that
62
+ would run every test serially. `gate_started` now records which form ran
63
+ and why. The new `project.lane_seed` option copies such ignored caches into
64
+ a lane from its dependency's lane, the integration worktree or the main
65
+ checkout, journalled as `lane_seeded`. Both fields are also accepted in
66
+ `maestro.gates.<type>`.
67
+ - **`amend-plan` amends a live `vinta-ai-maestro` run instead of rewriting
68
+ its branches.** When a run of the plan is running, paused, interrupted or
69
+ failed, the skill asks whether to amend it, then edits the plan and the
70
+ run's own workflow copy (`vinta-ai-maestro workflow`, so earlier operator and
71
+ coordinator amendments survive), commits both on `plan/<workflow-id>/base`
72
+ and applies them with `vinta-ai-maestro amend`, which rebases the done
73
+ phases the change reaches. Before, the plan file changed and the run went on
74
+ building its snapshot. The skill also carries operator recipes for a live
75
+ run: switching harness or model, switching the account a harness runs as,
76
+ resuming with the same policy flags, and moving the base forward. New
77
+ partial `plan-execution/partials/maestro-live-run.md`; re-run
78
+ `vinta-derive-skills` to pick it up.
79
+ - **`vinta-ai-maestro`: a phase the review keeps rejecting moves up a crew
80
+ tier.** One run left a Tier 1 phase on its desk through 16 review rejections
81
+ over six hours until the coordinator moved it by hand. New
82
+ `defaults.escalate_after_rejections` (default `3`, `0` turns it off): when a
83
+ phase's review has failed to approve that many times on one desk, counted
84
+ across attempts, the scheduler amends the run. The phase moves to the
85
+ cheapest member of the next tier up and takes the new desk from its next
86
+ attempt. The amendment is journalled as `workflow_amended` with the new
87
+ author `scheduler`, a one-line `reason` and a new `rule` field
88
+ (`review_rejections`, the members, the tiers and the count). A phase already at the top tier stays
89
+ where it is. Amendments may now leave a member the run already had with no
90
+ phase, so moving a member's last phase is no longer refused.
91
+ - **`vinta-ai-maestro`: `purge` drops lane rescues whose work landed.** The
92
+ `refs/vinta-ai-maestro/wip/*` commits a recycled lane keeps of a phase's
93
+ uncommitted files piled up (~80 in one project). A purge now drops those of
94
+ the runs it purges whose phase is done and merged into a branch outside
95
+ `plan/` and `wt/`, and those of already-purged runs whose rescued files read
96
+ the same at `HEAD`. Every other rescue is kept, and `--dry-run` lists them.
97
+ - **`vinta-ai-maestro`: a `ui` left up across an upgrade says so.** It warns
98
+ once when the installed package's version no longer matches the one it
99
+ loaded, and `run` and `status` warn about a live `ui` serving another
100
+ release. A `ui` started days earlier used to keep serving pre-upgrade code
101
+ without a word.
102
+ - **`vinta-ai-maestro`: a resume remembers how the run was started.** Every
103
+ job records its `--permission`, `--system-one`, `--on-failure`, `--retries`,
104
+ `--retry-after`, `--no-coordinator`, `--host` and `--harness-profile` in
105
+ `runs/<id>/policy.json`, and `run --resume` (and the UI's Resume) reuses
106
+ them, saying which; a flag given on the command line still wins. Each resume
107
+ used to need all of them restated.
108
+ - **`vinta-ai-maestro`: harness profiles.** `--harness-profile <name>` on `run`
109
+ and `ui` picks a named binary and environment for one harness — a second
110
+ Claude account's `CLAUDE_CONFIG_DIR`, say — from the operator's
111
+ `~/.config/vinta-ai-maestro/profiles.yaml` (or `$VINTA_AI_MAESTRO_PROFILES`).
112
+ The run keeps the name, so a resume picks the same account.
113
+ - **`vinta-ai-maestro`: `propagate` works on a live run.** It refused one, so
114
+ a fix on a phase could not reach older `integ-*` branches until the run
115
+ ended, and their PRs stayed red. On a live run the run's job now makes the
116
+ merges, holding the integration worktree's queue, so none of the run's own
117
+ merges interleave with them.
118
+ - **`vinta-ai-maestro`: `sync-base <run>` brings a moved `base_branch` into a
119
+ running plan.** It merges the base (the remote's, when ahead) into
120
+ `plan/<id>/base`, then the plan branch into the lowest wave and each wave
121
+ into the one above. On a live run a wave's conflict goes to the run's
122
+ conflict fixer, gated as a phase merge is; the plan branch's own conflict,
123
+ and any conflict on a run that is not live, stops it with the branch as it
124
+ was. Both commands journal `branches_moved` on a live run.
125
+ - **`vinta-ai-maestro`: a list of what the run decided without you.** One
126
+ run answered 79 of its 125 questions unattended — review loops stopped,
127
+ agents' design questions given their first option, one of which added a
128
+ migration — and none of it was anywhere a person would look. Every question
129
+ a `--retry-after` timer or the run coordinator answered, and everything the
130
+ coordinator did on its own (steering, pauses, aborts, amendments, `exec`),
131
+ is now listed in:
132
+ - `status <run>` (*Decided without you*; `unattended` in `--json`), with an
133
+ agent question's header and the option it got;
134
+ - the run view's **Decided without you** panel (`GET /api/runs/:runId/unattended`);
135
+ - the plan PR's *Decided without a person* section;
136
+ - the post-mortem's new optional `unattended_decisions` finding
137
+ (`schemas/postmortem.v1.schema.json`, additive), which `plan-feature`
138
+ now reads: an agent question answered unattended is a decision the plan
139
+ left open.
140
+ - **`vinta-ai-maestro`: merge resolutions that undo a phase's deletion are
141
+ flagged.** One run's phase deleted an unused notification kind; the
142
+ conflict fixer kept "both sides" and every gate passed, so the deletion
143
+ never landed. After every merge in the integration worktree — a fixer's
144
+ resolution, or the `append_only` union driver, which re-adds lines one side
145
+ removed — the integrator counts lines one side deleted that the result
146
+ kept (codegen outputs excluded). Each is recorded as path, phase and line
147
+ count, never the lines: on the `node_conflict` journal row
148
+ (`reverted_deletions`), in the post-mortem's `wave_conflicts` and new
149
+ optional `unattended_decisions.reverted_deletions`
150
+ (`schemas/postmortem.v1.schema.json`, additive), and in the list of what
151
+ was decided without you (`status`, the run view, the plan PR body). It
152
+ flags; it does not block the merge. The conflict-fixer prompt now says a
153
+ phase's intent includes what it deleted.
154
+ - **`vinta-ai-maestro`: `--agent-answer-after` on `run` and `ui`.** How long an
155
+ agent's own question waits before it takes the recommended options. It
156
+ used to be `--retry-after`, so a one-minute retry interval answered design
157
+ questions in a minute. Unset, it is twice `--retry-after` and never under 30
158
+ minutes; set alone, agents' questions are answered while failures still
159
+ wait for a person.
160
+ - **`vinta-ai-maestro`: `doctor` checks the gates against CI.** It reads
161
+ `.github/workflows/*.yml` and warns about each `run:` command no gate runs,
162
+ or runs without a flag CI passes (`manage.py check` for CI's `check
163
+ --deploy`) — the reason every gate passed while CI failed on twenty review
164
+ PRs of one run. Matching is heuristic (tool and subcommand after `uv run`,
165
+ `npx`, `docker compose run`, …; `uses:` steps are not read) and it is always
166
+ a warning.
167
+ - **`vinta-ai-maestro`: project-wide custom gates.** `maestro.gates` in
168
+ `.vinta-ai-workflows.yaml` now takes ids of your own beside the four types —
169
+ `django-check: { cmd: uv run python manage.py check --fail-level WARNING }`,
170
+ `api-client-fresh: { cmd: make api_client && git diff --exit-code … }` —
171
+ with the fields a type takes (`cmd`, `scoped_cmd`, `requires`, `timeout_s`,
172
+ `tuning`). Every plan has each one under its id without declaring it, and
173
+ `maestro.defaults.gates` names it like a type, so a check CI runs is
174
+ declared once and keeps its own verdict instead of being chained onto
175
+ `typecheck` or repeated in every plan. A plan's gate of the same id replaces
176
+ it whole. `validate` refuses an id that is not lowercase kebab-case, the
177
+ reserved `codegen`, and a custom gate with no `cmd`. Previously any key but
178
+ a type failed with "Unrecognized keys". Additive in the config schema.
179
+ `plan-feature` and the Django stack notes now point CI-mirroring checks at
180
+ `maestro.gates.<id>`.
181
+ - **`vinta-ai-maestro`: codegen steps — generated files are regenerated, not
182
+ merged.** A workflow (or `maestro.codegen` in `.vinta-ai-workflows.yaml`)
183
+ declares `codegen.<id>`: a deterministic command, the files it writes
184
+ (`outputs`), the files they are a function of (`inputs`), and `after` for the
185
+ chain (schema, then client). The steps run in every lane before the gates
186
+ and their outputs are committed there; in the integration worktree a
187
+ conflict confined to their outputs is settled by taking either side and
188
+ running them, with no conflict fixer, and every merge is regenerated before
189
+ it is committed. A failing step is a red gate. `inputs` skip a step whose
190
+ inputs and outputs match a recorded run, a step that writes different
191
+ outputs from the same inputs is journalled `nondeterministic`, and a
192
+ `format: true` step formats only the files the phase changed. Agents are told
193
+ which files are generated and regenerate them mid-turn with
194
+ `vinta-ai-maestro codegen [<step>]`; `doctor --codegen` runs each step twice
195
+ to flag non-deterministic or stale output. Generated files caused most of one
196
+ run's 37 wave conflicts. `workflow.v1` and the config schema gain the
197
+ additive `codegen` field.
198
+
199
+ - **`vinta-ai-maestro`: append-only files merge as a union.** `append_only` (or
200
+ `maestro.append_only`) lists files phases only add entries to — DI
201
+ containers, URL routes, notification kinds, beat schedules — and merges in
202
+ the integration worktree use git's `union` driver for them, so two phases
203
+ each adding an entry no longer needs a fixer round. The merged tree is gated
204
+ as before. Additive in `workflow.v1` and the config schema.
205
+
206
+ - **`plan-feature`: emits codegen steps and append-only files** detected from the
207
+ project — the OpenAPI schema, generated API clients, route trees and
208
+ file-modifying pre-commit hooks as `codegen`; DI containers, URL routes and
209
+ beat schedules as `append_only` — preferring `maestro.codegen` /
210
+ `maestro.append_only` in the project file. `vinta-bootstrap-ai-tools` offers
211
+ to record them there once.
212
+ - **`vinta-ai-maestro`: take a phase over without failing it.** Moving a phase
213
+ to another agent took abort, amend and retry, and the retry restarted its
214
+ pipeline from the top — one phase went from review back to implementing.
215
+ `node interrupt <run> <phase>` stops the turn now and **holds** the phase,
216
+ lane, branch, commits and uncommitted work kept, until `resume`, `reassign`
217
+ or `step` releases it; the cut step runs again then. `node reassign <run>
218
+ <phase> --crew <member> | --harness <h> --model <m>` is interrupt, amend and
219
+ resume in one (`--after-turn` lets the turn finish): the phase carries on at
220
+ the same step, keeps its session when only the model changes, and otherwise
221
+ starts fresh with a handoff — the last report, the work in the lane, the red
222
+ gate. `node step <run> <phase> <state>` moves the pipeline by hand, never
223
+ into a final state. Journalled as `node_reassigned` and `node_operation`.
224
+ - **`vinta-ai-maestro`: `amend` accepts a held phase, or one waiting on a
225
+ question.** Its harness, model or crew member (`crew_changed`, a new
226
+ amendment kind) may change while it is parked, and it carries on at its
227
+ step. A brief, a gate list or a base still waits for the phase to stop.
228
+ - **`vinta-ai-maestro`: `switch-harness <run> --from --to --model` and
229
+ `defaults.harness_fallbacks`.** A live run moves off a harness — an account
230
+ out of credits — without a pause and resume: phases in flight are
231
+ reassigned at their step, later phases run on the new harness, and the
232
+ conflict fixer moves too. With `harness_fallbacks` the run does it by
233
+ itself when a harness parks on a quota refusal, the refused turn going
234
+ again at once on the fallback. Journalled `harness_switched`.
235
+ - **`vinta-ai-maestro`: `fixer interrupt|reassign <run>`.** End the conflict
236
+ fixer's running round as a round spent (what it left stays), or hand later
237
+ rounds to another harness and model. Journalled `fixer_operation`.
238
+ - **`vinta-ai-maestro`: one API for the operator and the coordinator, and every
239
+ act says why.** Every acting request takes a reason (`--reason` on every
240
+ verb, the `X-Maestro-Reason` header on the API), journalled with what it
241
+ explains; the coordinator is refused without one (`reason_required`). The
242
+ coordinator gains `interrupt`, `reassign`, `switch-harness`, `fixer`,
243
+ `resume` of its own holds, and `pause` of the run (`run_halt_requested`).
244
+ `run --coordinator-authority full` also lets it change the plan's shape —
245
+ phases, dependency edges, briefs, touch lists, deferrals — answer any
246
+ question you are not holding, `node step`, and stop the run. A check is
247
+ never weakened under either authority.
248
+
38
249
  - **`vinta-ai-maestro`: integration is visible while it happens.** A phase in
39
250
  `integrate` — a merge, a suite on the merged tree, a push, none with an
40
251
  agent — showed `running` over a silent transcript, and one queued behind it
@@ -659,6 +870,97 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
659
870
 
660
871
  ### Changed
661
872
 
873
+ - **`vinta-ai-maestro`: the coordinator's wakes are more specific.**
874
+ - The `gate_cost` wake lists uncached minutes per phase and flags any
875
+ single run of 20 minutes or more as probably a cold lane. Runs of a
876
+ gate's `cold_cmd` no longer count toward the total.
877
+ - A failed attempt does not wake the coordinator when it already acted on
878
+ that phase during the attempt.
879
+ - A session that ends with shell calls that never returned is journalled
880
+ as `tool_calls_unfinished` and wakes the coordinator.
881
+ - `amend` lists the affected phases that are running or waiting, which pick
882
+ up the change only once they stop.
883
+ - **Bootstrap asks about maestro's test gate in lanes.** In the maestro
884
+ defaults (C.11), bootstrap now asks:
885
+ - whether a cache-based scoped run (`pytest --testmon`) should fall back to
886
+ the full parallel suite in a lane with no cache. This emits
887
+ `scope_cache`, `cold_cmd` and `project.lane_seed`, and proposes a
888
+ `test_changed` target that falls back when `.testmondata` is missing.
889
+ It also explains that `--testmon` with `-n` trades correctness for speed.
890
+ - whether a suite that reuses its database should get a fresh-database form
891
+ for the integration worktree. This emits `fresh_cmd` and
892
+ `tuning.allowed_flags: ['--create-db']`.
893
+ - for each CI check with no gate, whether to add a gate or record it under
894
+ `maestro.ci_only` with a reason.
895
+ - **Django stack notes** cover database reuse and testmon in lanes, keeping
896
+ the virtual environment out of a bind-mounted worktree
897
+ (`UV_PROJECT_ENVIRONMENT=/opt/venv`, `user: "${UID}:${GID}"`), registries
898
+ every phase appends to, and drf-spectacular `ENUM_NAME_OVERRIDES` for new
899
+ choice fields.
900
+ - **`plan-feature`** names the enum for same-named choice fields that two
901
+ phases expose, lists the usual append-only registries, and records CI
902
+ checks that cannot run locally under `ci_only`.
903
+ - **`plan-feature`: a rename of a shared symbol is an interface change.** A
904
+ phase that renames something a same-wave sibling also uses does it in the
905
+ foundation phase or keeps the old name as an alias until the wave lands.
906
+ One run had a phase call a helper its sibling renamed; each passed alone and
907
+ the merged wave failed the typecheck.
908
+ - **`plan-feature`: gates cover what CI runs.** The workflow rules now tell the
909
+ author to read the CI config and give every locally runnable CI job a gate,
910
+ naming the checks plans miss: a deploy check at warning level, a
911
+ migrations-complete check, a "generated client is up to date" check. The
912
+ Django stack notes suggest `manage.py check --deploy --fail-level WARNING`,
913
+ `makemigrations --check` and a regenerate-and-diff gate for the schema or
914
+ client. One run's regex-style routes passed every gate and failed CI.
915
+ - **`write-unit-test`: time-independent tests and deterministic generated
916
+ output.** Rule 8 now requires a frozen clock and an explicit timezone on any
917
+ test touching dates, and host-independent schema or client generation
918
+ (values from a locked package such as `tzdata`, sorted). The Django pack and
919
+ stack notes spell out `freezegun` / `time-machine` with
920
+ `override_settings(TIME_ZONE=...)` and `tzdata`-sourced timezone choices.
921
+ One run had a date test fail only near midnight UTC, and a timezone enum
922
+ differ by machine.
923
+ - **`vinta-bootstrap-ai-tools`: test-tool caches are ignored before lanes run.**
924
+ The maestro defaults step reads `.gitignore` for the selected runners'
925
+ caches and reports (`.testmondata*`, `junit/`, coverage outputs, …),
926
+ checks for the `check-added-large-files` pre-commit hook, which a committed
927
+ testmon database trips on every lane and merge commit, and offers to append
928
+ the missing entries.
929
+ - **`vinta-ai-maestro`: a review that stated no verdict is no longer reported
930
+ as a rejection.** One run recorded 22 attempts as `review verdict "fail"; 0
931
+ fix rounds spent`. None had rejected anything: each was a review turn that
932
+ ended before its reviewer answered (fixed in alpha33 and alpha34). The
933
+ pipeline still treats silence as `fail`, but the failure reason now says
934
+ `the review turn stated no verdict`, and the `review` fact carries
935
+ `stated: false`. The budget clause is renamed to `gate fix rounds spent`,
936
+ since a review's findings are fixed inside its own turn and never in a
937
+ separate fix round.
938
+
939
+ - **`vinta-ai-maestro`: two empty turns in a row park the phase instead of
940
+ burning its retries.** Right after one run moved its desks to codex, "codex
941
+ ended the turn without the agent doing anything" failed 20 attempts across 4
942
+ phases in about two minutes. When one harness ends two turns in a row
943
+ without the agent doing anything, across attempts, the phase now skips its
944
+ automatic retries and asks: the question says the harness is failing and
945
+ suggests `retry with` a member on another harness. `--retry-after` still
946
+ answers it, and backs off from the first question.
947
+
948
+ - **`vinta-ai-maestro`: a red gate on a merged base is re-run on retry.** One
949
+ run's base test gate failed once on a test that broke only near midnight.
950
+ Seven retries replayed the cached verdict, each reported as "failed during
951
+ setup, before any agent ran", and the unattended retry was withheld until an
952
+ operator ran `gate-cache invalidate`. The base gates now replay only a green
953
+ verdict and re-run a red one, and a red base gate no longer counts as a
954
+ setup failure, so `--retry-after` keeps retrying it with its usual backoff.
955
+
956
+ - **`vinta-ai-maestro`: a lane that will not recycle says why.** One run
957
+ failed 20 attempts with only "could not be recycled (worktree)" or
958
+ "(database)" in the journal and the daemon log. The failure now carries the
959
+ failing step's exit code and the tail of its stderr, the way a failed
960
+ `setup_cmd` already did, and a `reset_cmd`, `setup_cmd` or `prepare_cmd`
961
+ failing during a recycle reports that command's own error instead of
962
+ `LaneSetupError`. Command lines are still left out.
963
+
662
964
  - **`vinta-ai-maestro`: the full suite runs before a PR, and on every merged
663
965
  tree.** Under `gate_scope: scoped`, a phase's gates ran their scoped form
664
966
  everywhere, so a PR could carry a suite only a scoped run had seen, and most
@@ -1031,6 +1333,110 @@ the project follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
1031
1333
 
1032
1334
  ### Fixed
1033
1335
 
1336
+ - **`vinta-ai-maestro`: a review chore can no longer leave the lane dirty.**
1337
+ Whatever a review leaves uncommitted, such as a mutation experiment's
1338
+ reverted migration or a generated file, is set aside under a
1339
+ `refs/vinta-ai-maestro/wip/` ref. The lane is then reset to `HEAD` before
1340
+ the gates run, and `review_left_lane_dirty` is journalled. The implementer
1341
+ and conflict-fixer prompts now say to run one test command at a time per
1342
+ lane, to check `docker ps` for leftover run containers, and to treat a
1343
+ single test file that runs past two minutes as a lock or hang.
1344
+ - **Plan-execution prompts and the review-canvas chore.** The implementer
1345
+ prompt adds the same shared-test-resource rules. The conflict fixer
1346
+ reports `ENVIRONMENT_STALE` (and changes no code) when the merged tree's
1347
+ failures are columns or tables no model defines, and syntax-checks the
1348
+ files git auto-merged. The reviewer leaves the worktree as it found it:
1349
+ mutation experiments run in a throwaway worktree. `plan-feature`'s review
1350
+ chore prompt says so too. Its review-canvas chore passes
1351
+ `--data-dir .pr-review` inside the lane, and setup ignores `.pr-review/`.
1352
+ - **`vinta-ai-maestro`: conflicts in generated files no longer fail a
1353
+ merge.** After each conflict-fixer round, codegen outputs that the round
1354
+ left conflicted, or staged with conflict markers, are settled again and
1355
+ regenerated, even when the fixer aborted and redid the merge. The fixer's
1356
+ prompt now matches: with codegen declared, generated files are the
1357
+ integrator's; with none declared, every conflicted file is the fixer's. An
1358
+ unresolved conflict over files that look generated suggests declaring a
1359
+ `codegen` step.
1360
+ - **`vinta-ai-maestro`: `exec` streams, accepts `--reason`, and can be
1361
+ cancelled.** The daemon used to read each answer whole before sending
1362
+ it, so an `exec` queued behind the integration worktree sent nothing, and
1363
+ the client said the run was "not live" while the command still ran later.
1364
+ The answer now streams. The client says who it is queued behind, and
1365
+ ending the client cancels the command, whether it is queued or running.
1366
+ `--reason` is journalled. `exec --detach`, `exec list <run>` and
1367
+ `exec cancel <run> <id>` are new. Every release of the integration
1368
+ worktree lets the next waiter in.
1369
+ - **`vinta-ai-maestro`: a paused phase no longer takes the integration
1370
+ worktree.** A paused node waiting in the integration queue keeps its place
1371
+ but is passed over, and is let in once it is resumed. This is journalled
1372
+ as `node_wait` with state `paused`. `status` shows a node as paused as soon
1373
+ as the pause is sent, not only once it takes effect.
1374
+ - **`vinta-ai-maestro`: a lane that cannot be recycled no longer fails the
1375
+ phase handed to it.** A recycle that fails (outside the `preserve` stage)
1376
+ takes that lane out of the run and provisions a fresh one, `<lane>-r<N>`,
1377
+ and the phase runs there with nothing charged. The old lane stays on disk
1378
+ and is journalled as `lane_unhealthy`, with any paths git could not remove
1379
+ and their owner's uid. `status` shows it.
1380
+ - **`vinta-ai-maestro`: a provider or network outage no longer fails
1381
+ phases.** A turn that ends on an infrastructure error (DNS or connection
1382
+ failures, `upstream-unavailable`, HTTP 5xx or 529, an expired or rejected
1383
+ login) parks the harness with backoff and re-runs the phase when the
1384
+ harness answers. Nothing is charged to its attempts, retries or
1385
+ "N failures in a row" count. A lapsed login is asked once per harness, not
1386
+ once per phase. Each outage is journalled as `outage_started` /
1387
+ `outage_ended`, and `status` shows a line for every open one. The
1388
+ coordinator's digest no longer lists error lines from before a phase's
1389
+ last session that ended well.
1390
+ - **`vinta-ai-maestro`: integration gates no longer run against a test
1391
+ database left by another branch.** A command gate may declare `fresh_cmd`
1392
+ (also in `maestro.gates.<type>`), the same check from a fresh database (for
1393
+ example `pytest --create-db`). In the integration worktree it runs instead
1394
+ of `cmd` in four cases: when the tree moved anywhere but forward since the
1395
+ gate last ran there, on the gate's first run there, once more after a red
1396
+ run whose output shows missing or extra columns or relations, and after a
1397
+ conflict fixer ends its turn on `ENVIRONMENT_STALE`. That last round is
1398
+ given back. Each fresh run is journalled as `integration_fresh_state`.
1399
+ - **`vinta-ai-maestro`: a killed gate no longer leaves its Docker container
1400
+ running.** A timed-out or cancelled gate, `with` command or `exec` also
1401
+ removes the one-off `docker compose run` containers its lane's compose
1402
+ project started since the command began, before the pools, lease or
1403
+ integration worktree it held are released. A sweep every five minutes
1404
+ removes one-off containers in lanes no phase or `exec` is using, journalled
1405
+ as `orphan_containers_stopped`. Without docker, nothing changes.
1406
+ - **`vinta-ai-maestro`: the integrator no longer stages untracked files into
1407
+ a merge resolution.** It stages tracked paths and the merge's own paths
1408
+ instead of `git add --all`, so a gate's leftovers in the integration
1409
+ worktree (a `.testmondata-wal`, say) stay out of the merge commit. A kept
1410
+ resolution that changes paths outside the merge, or whose commit is refused
1411
+ again, is dropped instead of replayed on every retry. A conflict fixer now
1412
+ stages any new file it creates itself, and its prompt says so.
1413
+ - **`vinta-ai-maestro`: an amendment reaches the conflict fixer.** The fixer
1414
+ is rebuilt from the amended crew when the plan is amended, so a run whose
1415
+ desks moved to another harness stops failing on "conflict fixer spawn
1416
+ refused" for the harness it left.
1417
+ - **`vinta-ai-maestro`: a conflict fixer stopped by its time limit keeps its
1418
+ work.** What the round had is kept under `refs/vinta-ai-maestro/abandoned/`
1419
+ (an interrupted round's too), and the retry's fixer is pointed at it to
1420
+ continue instead of redoing the resolution from scratch.
1421
+ - **`vinta-ai-maestro`: an amended harness reaches every phase it moved.** An
1422
+ amendment changed the harness only on phases still `pending`; a failed or
1423
+ blocked one waiting on a retry kept naming the old harness in `status` and
1424
+ the run view, and once the job loaded only the new harness's adapter the
1425
+ run view answered 500 `unknown harness`. Phases past `pending` now take the
1426
+ new harness without losing their status, and the run view leaves out the
1427
+ capacity of a harness the live run loaded no adapter for.
1428
+ - **`vinta-ai-maestro`: `land` decides "already in the base" by content.** A
1429
+ review PR is landed when merging it into the base would leave the base's
1430
+ tree unchanged. The ancestry test it used alone kept an `integ-*` PR open
1431
+ after its plan PR merged: three bookkeeping merges were not in `main`, though
1432
+ every branch they merged was. A draft plan PR is now named as one (GitHub
1433
+ will not merge a draft), and `land <run> --ready` marks it ready for review.
1434
+ - **`vinta-ai-maestro`: a hook that rewrites files no longer refuses the
1435
+ commit outright.** When a commit fails having left modified files behind — a
1436
+ `pre-commit` formatter or schema generator — they are staged and the commit
1437
+ is tried once more before the operator is asked, in lanes and in the
1438
+ integration worktree. One run had seven merge commits refused this way.
1439
+
1034
1440
  - **`vinta-ai-maestro`: a claude-code turn the CLI calls "blocked" no longer
1035
1441
  fails unless a tool was refused in it.** The CLI's own turn summary marks a
1036
1442
  turn `blocked` whenever its last message names a next step for a person —
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "vinta-ai-workflows",
3
- "version": "0.7.0-alpha35",
3
+ "version": "0.7.0-alpha37",
4
4
  "description": "Bootstrap AI tooling (AGENTS.md, skills, sub-agents) across Claude Code, Codex, Cursor, and VS Code + GitHub Copilot.",
5
5
  "type": "module",
6
6
  "bin": {