Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 3 additions & 3 deletions AGENTS.md
Original file line number Diff line number Diff line change
Expand Up @@ -408,7 +408,7 @@ Parent。软缺口(`soft_continue=true`)下 `swarm_doctor` 同样给出
这条引导上 `fixes` 不把 `evolver doctor --fix` 列为当前步骤;boot/status,以及
第一次未完成 run 的 tick 与保险丝,其 `commands` 与 `next_steps` 同样不把它当成
现在要执行的修复。没有未完成 run,或固化之后,列出这条命令仍然合适。本工具仍不执行它。
tick / 保险丝上的 `gate_soft_continue` 仍缺席,不写成 false。
有软缺口时,第一次 tick 与保险丝写 `gate_soft_continue=true`,不写成 false。
硬阻断的 doctor 仍是 `ok=false`,不另给这个动作,也不写 `tick_again`。
此时 `boot_once` 为空。忽略 `next_action` 再调 `swarm_tick` 时默认不启新周期。
第一次 `ok=true`、`severity=soft`、`cycle_started=false`、`progress=false`、
Expand All @@ -422,8 +422,8 @@ tick / 保险丝上的 `gate_soft_continue` 仍缺席,不写成 false。
不把裸码当成 `next_action`。软缺口留在 `warning`。两次返回都带
`preserve_pending=true`、`abandon_run=false`、
`action_required=swarm_solidify`(boot/status 在仍要固化时同样带上)。有软缺口时,
第一次 tick 与保险丝都不带 `gate_soft_continue`(缺席不是 false;`ok` 第一次仍为 true,
没有 `error`;`tick_again=false` 与 `retryable=false` 都表示不要再 tick,第一次也写 `retryable=false`,缺席不再当成可以再 tick)。两次 tick 都带
有软缺口时,第一次 tick 与保险丝都写 `gate_soft_continue=true`(true 不是 false,也不是再 tick 的许可;`ok` 第一次仍为 true,
没有 `error`;`tick_again=false` 与 `retryable=false` 都表示不要再 tick,第一次也写 `retryable=false`)。两次 tick 都带
`session_not_failed=true`:先读它,会话没有失败。`loop_fuse` 不在 `error` 里,
preserve 三元组仍指向 `swarm_solidify`。
boot/status 的 `gate_soft_continue` 仍为 true,且不带 `session_not_failed`。未完成 run 的软缺口 boot/status 同时写 `tick_again=false`(只看 `gate_soft_continue=true` 的宿主仍可能再 tick)。
Expand Down
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
## Unreleased

### Fixed
- **MCP 宿主可用性:未完成 run 的软缺口 tick 与保险丝写 `gate_soft_continue=true`**:第一次未完成 run 的 `swarm_tick`,以及同一条 run 再 tick 的 `loop_fuse=pending_redirect_loop`,在软缺口上保留 `apply_soft_gap` 写下的 `gate_soft_continue=true`,与 boot / status 同一口径。这个键不写成 false。`tick_again=false`、`retryable=false`、保险丝的 `ok=false`、`session_not_failed` 与 preserve 三元组不动。没有软缺口的重定向仍不写这个键。doctor 仍不写。不结算这条 run,不写 Parent baseline,不放宽固化门,不执行 `evolver doctor --fix`。
- **MCP 宿主可用性:未完成 run 的第一次 tick 与保险丝也不把 `evolver doctor --fix` 当当前步骤**:软缺口固化引导上,第一次 `swarm_tick` 与 `loop_fuse=pending_redirect_loop` 的 `commands` 去掉精确的 `evolver doctor --fix`,`next_steps` 里点名它的句子改成先 `swarm_solidify`(`next_action` / preserve / `action_required`)。`gate_soft_continue` 在这两份信封上仍缺席,不写成 false。`tick_again=false` 与保险丝的 `ok=false` 不动。没有未完成 run 的 tick、boot、doctor 仍列出这条命令。本工具仍不执行 `--fix`。不结算这条 run,不写 Parent baseline,不放宽固化门。
- **MCP 宿主可用性:软缺口固化引导不再把 `evolver doctor --fix` 当当前步骤**:未完成 run 且 soft-continue 时,`swarm_doctor` 的 `fixes` 去掉这条命令。boot / status 的 `commands` 同样去掉它,`next_steps` 里点名它的句子改成先 `swarm_solidify`(`next_action` / preserve / `action_required`)。`soft_continue` 仍为 true,`gate_soft_continue` 在 boot/status 仍为 true,doctor 仍不写这个键,也不写 `session_not_failed`。没有未完成 run 时,`fixes` / `commands` 仍列出 `evolver doctor --fix`。固化之后同样可以再列。本工具仍不执行 `--fix`。第一次 tick 与保险丝的 `commands` 不动。不结算这条 run,不写 Parent baseline,不放宽固化门。
- **MCP 宿主可用性:未完成 run 的软缺口 boot/status 写 `tick_again=false`**:`swarm_boot` 与 `swarm_status` 在未完成 run 且软缺口、`next_action=swarm_solidify` 时带 `tick_again=false`。`gate_soft_continue` 仍为 true,不写 `session_not_failed`。preserve 三元组不动。没有未完成 run 的 soft-continue,以及压缩检查点盖过固化时,不写 `tick_again`。doctor、第一次 tick 与保险丝本来的 `tick_again=false` 不动。不结算这条 run,不写 Parent baseline,不放宽固化门。
Expand Down
8 changes: 8 additions & 0 deletions DEBUG.md
Original file line number Diff line number Diff line change
Expand Up @@ -1265,3 +1265,11 @@
- **修复**:第一次未完成 run 的 tick 与保险丝在 `next_action=swarm_solidify` 时,`commands` 去掉精确的 `evolver doctor --fix`,`next_steps` 里点名它的句子改成先 `swarm_solidify`。`gate_soft_continue` 仍缺席,不写成 false。`tick_again=false` 不动。保险丝的 `ok` 仍为 false。没有未完成 run 的 tick 仍列出这条命令。不结算,不写 Parent baseline,不放宽固化门,不执行 `--fix`。目录缓存(DEBUG #61)未做假修复。
- **经验**:**当前步骤的清单要盖住宿主下一步会读的每一份信封。** 开机回执拿掉一条命令之后,重定向信封若仍列出它,宿主会从 tick 的返回里把它捡回来。
- **仍在**:只看 `soft_continue=true` 或把缺席的 `gate_soft_continue` 当成继续、完全不看 `tick_again` / `next_action` / `commands` 的宿主,仍可能再 tick。没有把这些旗标写成 false(会重开 DEBUG #67)。`commands` 里仍可能有 `evolver bench freeze` 与 `evolver bench baseline`。把保险丝 `ok=false` 当成整段失败、且不读 `session_not_failed` 与 `loop_fuse` 的宿主(DEBUG #68 余项 2)仍会停掉会话;`ok` 留着 false。目录缓存(DEBUG #61)没有做假修复。

### 75. 只认 `gate_soft_continue` 的宿主在 tick 与保险丝上看不到软缺口(MCP 易用性,已修)

- **症状**:#67 之后,未完成 run 的软缺口 boot / status 写 `gate_soft_continue=true`。同一条 run 的第一次 `swarm_tick` 与 `loop_fuse=pending_redirect_loop` 把这个键删掉。只在键为 true 时才认出 soft-continue 的宿主,在这两份信封上错过软缺口,尽管 `warning` 里仍是建议、`tick_again=false` 已经表示不要再 tick。doctor 仍不写这个键。
- **根因**:`apply_soft_gap` 把旗标写成 true。`_prefer_solidify_steps(hold_tick=True)` 再 `pop` 掉,用来同时躲开「只在 true 时 tick」和「只在 false 时判死」。boot / status 没有这次 pop。缺键对只认这个键的宿主等于「没有软缺口」。
- **修复**:软缺口上的第一次 tick 与保险丝保留 true,并在 `hold_tick` 上再写一次 true,不写 false。停 tick 仍看 `tick_again=false`、`retryable=false`、`next_action=swarm_solidify`,保险丝的 `ok` 仍为 false。`session_not_failed` 与 preserve 三元组不动。没有软缺口的重定向不写这个键。doctor 仍不写。`commands` 里 `evolver doctor --fix` 的延后不动。不结算,不写 Parent baseline,不放宽固化门,不执行 `--fix`。目录缓存(DEBUG #61)未做假修复。
- **经验**:**软缺口旗标的原义是「缺口是建议」,停 tick 要写在 `tick_again` 上。** 把 true 从 tick 信封拿掉,只认这个键的宿主就和 boot 对不上。写成 false 会重开 DEBUG #67。
- **仍在**:只看 `gate_soft_continue=true`、完全不看 `tick_again` / `next_action` / `ok` / `retryable` 的宿主,第一次 tick 与保险丝之后仍可能再 tick。没有把这个旗标写成 false。doctor 仍不写 `gate_soft_continue`,只读 `soft_continue=true` 的冒烟余项仍在。把保险丝 `ok=false` 当成整段失败、且不读 `session_not_failed` 与 `loop_fuse` 的宿主(DEBUG #68 余项 2)仍会停掉会话;`ok` 留着 false。`commands` 里仍可能有 `evolver bench freeze` 与 `evolver bench baseline`。目录缓存(DEBUG #61)没有做假修复。
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -239,9 +239,9 @@ After `uv sync`, a pull, or any install, **restart the MCP server**. A long-live

Live `tools/list` already publishes `swarm_tick` parameters `prompt_mode` (`full` or `short`) and `checklist_only`, with descriptions on those fields, and read-only `swarm_doctor`. A host catalog that still lists only `agent_name` and `include_prompt`, or that cannot find `swarm_doctor`, is a stale client session. Restarting the server reloads the code; start a new host session so the client reads `tools/list` again.

If a previous run is unfinished, `swarm_boot` keeps `next_action=swarm_solidify`, sets top-level `pending_solidify`, and adds `readonly_smoke` (`tools`: `swarm_doctor` and `swarm_status`, `settles_run`: false). On a soft gap it also sets `tick_again=false` while `gate_soft_continue` stays true. `hint` says to solidify first. A soft gap (`no_baseline` / `pack_absent` / `unmeasured`) still attaches `warning` and `next_steps`, and it does not replace that hint or weaken the gate. A read-only smoke can call `swarm_doctor` or `swarm_status`; neither settles the run nor invents a Parent baseline. A `swarm_tick` in that state does not start a cycle. The first call stays soft (`ok` true, `severity` soft, `cycle_started` false, `progress` false, `redirect_count` 1, `retryable` false, `next_action` still `swarm_solidify`, `last_run` unchanged). An omitted `retryable` is not a license to tick again. The same call again on that run returns `ok` false, `loop_fuse=pending_redirect_loop`, `redirect_reason=pending_redirect_loop`, `severity` soft, `retryable` false, and no `error` field. It still does not start a cycle. `loop_fuse` and that `redirect_reason` are the tick-loop fuse. The code is not an `error` and not a `next_action`. `next_action` stays `swarm_solidify`. `dispatch_reason` stays `pending_solidify`. The first redirect keeps `redirect_reason=pending_solidify` and does not set `loop_fuse`. Connect-time instructions name `loop_fuse=pending_redirect_loop` the same way. The fuse is not a gate failure and not an abandon signal; a soft gap stays on `warning` and `next_steps`. Both returns set `preserve_pending` true, `abandon_run` false, and `action_required` to `swarm_solidify` (boot and status do too while solidify is still next). Do not drop the unfinished run. When a soft gap is present, `gate_soft_continue` is omitted on the first redirect and on the fuse (`tick_again` is false). Omitted is not false: the first redirect keeps `ok` true and sets no `error`, so a host that treats only a strict false as session death stays in the session and does not tick again. Both tick returns set `session_not_failed` true. Read that field before other flags: true means the session is not failed, and `loop_fuse` does not abandon the run when the preserve flags say to call `swarm_solidify`. `next_steps` starts with `swarm_solidify`. Boot and status keep `gate_soft_continue` true while a run is still unfinished, set `tick_again` false on that soft gap, and they do not set `session_not_failed`. Pass `supersede_pending=true` to replace that run. Pause and the compaction checkpoint still refuse the cycle.
If a previous run is unfinished, `swarm_boot` keeps `next_action=swarm_solidify`, sets top-level `pending_solidify`, and adds `readonly_smoke` (`tools`: `swarm_doctor` and `swarm_status`, `settles_run`: false). On a soft gap it also sets `tick_again=false` while `gate_soft_continue` stays true. `hint` says to solidify first. A soft gap (`no_baseline` / `pack_absent` / `unmeasured`) still attaches `warning` and `next_steps`, and it does not replace that hint or weaken the gate. A read-only smoke can call `swarm_doctor` or `swarm_status`; neither settles the run nor invents a Parent baseline. A `swarm_tick` in that state does not start a cycle. The first call stays soft (`ok` true, `severity` soft, `cycle_started` false, `progress` false, `redirect_count` 1, `retryable` false, `next_action` still `swarm_solidify`, `last_run` unchanged). An omitted `retryable` is not a license to tick again. The same call again on that run returns `ok` false, `loop_fuse=pending_redirect_loop`, `redirect_reason=pending_redirect_loop`, `severity` soft, `retryable` false, and no `error` field. It still does not start a cycle. `loop_fuse` and that `redirect_reason` are the tick-loop fuse. The code is not an `error` and not a `next_action`. `next_action` stays `swarm_solidify`. `dispatch_reason` stays `pending_solidify`. The first redirect keeps `redirect_reason=pending_solidify` and does not set `loop_fuse`. Connect-time instructions name `loop_fuse=pending_redirect_loop` the same way. The fuse is not a gate failure and not an abandon signal; a soft gap stays on `warning` and `next_steps`. Both returns set `preserve_pending` true, `abandon_run` false, and `action_required` to `swarm_solidify` (boot and status do too while solidify is still next). Do not drop the unfinished run. When a soft gap is present, `gate_soft_continue` is true on the first redirect and on the fuse (`tick_again` is false). True is not false and not a license to tick: the first redirect keeps `ok` true and sets no `error`, so a host that treats only a strict false as session death stays in the session. Stop-tick stays on `tick_again` and `retryable`. This path never writes `gate_soft_continue=false`. Both tick returns set `session_not_failed` true. Read that field before other flags: true means the session is not failed, and `loop_fuse` does not abandon the run when the preserve flags say to call `swarm_solidify`. `next_steps` starts with `swarm_solidify`. Boot and status keep `gate_soft_continue` true while a run is still unfinished, set `tick_again` false on that soft gap, and they do not set `session_not_failed`. Pass `supersede_pending=true` to replace that run. Pause and the compaction checkpoint still refuse the cycle.

A cold `swarm_status` (this process has not called `swarm_boot`) returns `next_action=swarm_boot` and a short hint. After boot, status keeps `agent_name`, `source_revision`, and any soft `gap` / warnings. `tool_asset_search`, `tool_mailbox_poll`, `tool_cycle_timeline`, and `swarm_approvals` always return `{ok, items, hint}` — an empty match is not a blank body. `swarm_approvals` also keeps `pending` (the same rows as `items`) and `recent`. Read-only `swarm_doctor` mirrors `evolver doctor` without `--fix` (`ok`, soft warnings, command hints in `fixes`). `no_baseline` / `pack_absent` / `unmeasured` stay soft-continue. When a run is unfinished and that report is soft-continue, doctor also sets `next_action=swarm_solidify`, `tick_again=false`, `pending_solidify`, and the preserve triad (`preserve_pending`, `abandon_run=false`, `action_required=swarm_solidify`). `soft_continue` stays true. It still does not settle the run, write a Parent baseline, or execute `evolver doctor --fix`. On that steer, `fixes` does not list `evolver doctor --fix` as a current step. Boot and status `commands` and `next_steps` do not present it as the current action either. The first unfinished-run tick and the `loop_fuse=pending_redirect_loop` envelope do the same in `commands` and `next_steps`. `gate_soft_continue` stays omitted on those tick envelopes. The command stays listed when no run is unfinished, and after solidify. `gate_soft_continue` and `session_not_failed` stay absent. A hard blocker keeps `ok` false and does not add that action or `tick_again`. The first unfinished-run tick and the fuse already set `tick_again` false.
A cold `swarm_status` (this process has not called `swarm_boot`) returns `next_action=swarm_boot` and a short hint. After boot, status keeps `agent_name`, `source_revision`, and any soft `gap` / warnings. `tool_asset_search`, `tool_mailbox_poll`, `tool_cycle_timeline`, and `swarm_approvals` always return `{ok, items, hint}` — an empty match is not a blank body. `swarm_approvals` also keeps `pending` (the same rows as `items`) and `recent`. Read-only `swarm_doctor` mirrors `evolver doctor` without `--fix` (`ok`, soft warnings, command hints in `fixes`). `no_baseline` / `pack_absent` / `unmeasured` stay soft-continue. When a run is unfinished and that report is soft-continue, doctor also sets `next_action=swarm_solidify`, `tick_again=false`, `pending_solidify`, and the preserve triad (`preserve_pending`, `abandon_run=false`, `action_required=swarm_solidify`). `soft_continue` stays true. It still does not settle the run, write a Parent baseline, or execute `evolver doctor --fix`. On that steer, `fixes` does not list `evolver doctor --fix` as a current step. Boot and status `commands` and `next_steps` do not present it as the current action either. The first unfinished-run tick and the `loop_fuse=pending_redirect_loop` envelope do the same in `commands` and `next_steps`. `gate_soft_continue` is true on those soft-gap tick envelopes and is never false. The command stays listed when no run is unfinished, and after solidify. Doctor still leaves `gate_soft_continue` and `session_not_failed` absent. A hard blocker keeps `ok` false and does not add that action or `tick_again`. The first unfinished-run tick and the fuse already set `tick_again` false.

`swarm_boot(project=...)` binds a directory only when that path exists. `bound_paths.repo_root` is the code root (the git root walked from that directory, or the directory itself). `bound_paths.workspace_root` is the mutation directory. When they differ, or when `project` is a free-text label rather than a directory, the same object carries `warning` and `next_steps`. That is a soft warning: `ok` stays true and the loop still continues. A label is not turned into a new workspace.

Expand Down
Loading
Loading