Commit Graph

33 Commits

Author SHA1 Message Date
dave 1506141155 huskies: merge 1072 2026-05-15 01:27:25 +00:00
dave bb6a6063e8 huskies: merge 1066 2026-05-14 23:45:53 +00:00
Timmy e6865a1bc6 fix: stop event-triggers Lagged handler from re-emitting via the same channel
Merge 1061 added a replay_current_pipeline_state() call to the broadcast::Lagged
branch, but replay broadcasts one event per CRDT item (~997) into a 256-slot
channel, deterministically re-overflowing it and triggering another Lagged. The
loop pinned CPU and likely caused today's machine crash. Revert to the pre-1061
behaviour of logging and continuing.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-14 22:33:14 +01:00
dave 8f666bd6b3 huskies: merge 1062 2026-05-14 20:36:51 +00:00
dave 5678f2a556 huskies: merge 1061 2026-05-14 20:12:51 +00:00
dave b9709a6466 huskies: merge 1052 2026-05-14 18:11:57 +00:00
dave 1f9f34ab58 huskies: merge 1038 2026-05-14 17:06:50 +00:00
dave 311883f45d huskies: merge 1039 2026-05-14 16:33:47 +00:00
dave c64deca7c2 huskies: merge 1023 2026-05-14 11:24:05 +00:00
Timmy 8e996e2bd3 fix(1025): gate auto-block counter on mergemaster presence
1018's merge_failure_block_subscriber counted every MergeFailure transition
toward the 3-strike block threshold, but mergemaster's recovery iterations
(squash → fail → fix → retry) emit multiple MergeFailure transitions while
making real progress. Story 997 was blocked at 10:59:46 while mergemaster
was still resolving conflicts and would have succeeded a minute later.

Fix: pass the AgentPool to the subscriber. When a mergemaster agent is in
the pool for the story, MergeFailure transitions are recovery iterations
in progress and do NOT increment the consecutive-failure counter. Block
only fires for the genuinely-stuck case (no recovery agent attached and N
consecutive failures accumulate).

Tests:
- mergemaster_running_suppresses_block: 3 failures with recovery_running=true
  → counter stays empty, story stays in MergeFailure
- no_mergemaster_still_blocks_at_threshold: 3 failures with recovery_running=false
  → blocks (1018 behaviour preserved)

All 2938 tests pass.
2026-05-14 12:13:37 +01:00
dave 309542cf2c huskies: merge 1018 2026-05-14 09:38:15 +00:00
dave e3f5875b8e huskies: merge 1019 2026-05-14 08:52:38 +00:00
dave 4520e0e6f9 huskies: merge 995 2026-05-14 07:55:40 +00:00
dave 52180bc402 huskies: merge 1017 2026-05-13 23:55:35 +00:00
dave 29e800da21 huskies: merge 1016 2026-05-13 23:51:07 +00:00
dave 69b207872a huskies: merge 1014 2026-05-13 23:25:10 +00:00
dave 4e007bb770 huskies: merge 1009 2026-05-13 22:55:05 +00:00
dave 1ee23e7bfe huskies: merge 996 2026-05-13 22:29:09 +00:00
dave cd9021fedf huskies: merge 1006 2026-05-13 21:41:39 +00:00
dave bbdee1239b huskies: merge 998 2026-05-13 19:33:33 +00:00
dave 580480094e huskies: merge 984 2026-05-13 16:47:51 +00:00
dave c3c9db3d8b huskies: merge 987 2026-05-13 16:30:31 +00:00
dave 77dc09668c huskies: merge 960 2026-05-13 13:24:15 +00:00
dave 28338a8e8d huskies: merge 958 2026-05-13 11:52:51 +00:00
Timmy d78dd9e8f9 feat(934): typed Stage enum replaces directory-string state model
The state machine's `Stage` enum becomes the source of truth for pipeline
state. Six stages of work land together:

  1. Clean wire vocabulary (`coding`, `merge`, `merge_failure`, ...) replaces
     legacy directory-style strings (`2_current`, `4_merge`, ...) on the wire.
     `Stage::from_dir` accepted both during deployment; new writes always
     emit the clean form via `stage_dir_name`. Lexicographic `dir >= "5_done"`
     checks in lifecycle.rs become typed `matches!` checks since the new
     vocabulary doesn't sort in pipeline order.
  2. `crdt_state::write_item` takes typed `&Stage`, serialising via
     `stage_dir_name` at the CRDT boundary. `#[cfg(test)] write_item_str`
     parses legacy strings for test fixtures.
  3. `WorkItem::stage()` returns typed `crdt_state::Stage`; `stage_str()`
     is gone from the public API. Projection dispatches on the typed enum.
  4. `frozen` becomes an orthogonal CRDT register. `Stage::Frozen` and
     `PipelineEvent::Freeze`/`Unfreeze` are removed; `transition_to_frozen`/
     `unfrozen` set the flag directly without touching the stage register.
  5. Watcher sweep and `tool_update_story`'s `blocked` setter route through
     `apply_transition` so the typed transition table validates every
     stage change. `update_story` gains a `frozen` field for symmetry.
  6. One-shot startup migration rewrites pre-934 directory-style stage
     registers (and sets `frozen=true` on items previously at `7_frozen`).
     `Stage::from_dir` drops legacy aliases. The db boundary keeps a small
     normaliser so callers with legacy strings (MCP, tests) still work.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 22:31:59 +01:00
dave 22bf203853 huskies: merge 894 2026-05-12 13:02:53 +00:00
dave 9be438e6d3 huskies: merge 865 2026-05-08 14:29:06 +00:00
dave db526bbdb2 huskies: merge 876 2026-04-29 21:20:29 +00:00
dave 1ae8e8ec9d huskies: merge 841 2026-04-29 10:36:03 +00:00
dave dcd695ad0e huskies: merge 852 2026-04-29 08:55:49 +00:00
dave ab01a62bd1 huskies: merge 808 2026-04-28 23:18:57 +00:00
dave 97b9eaa39d huskies: merge 807 2026-04-28 20:56:17 +00:00
dave 46b1e84629 huskies: merge 791 2026-04-28 19:18:12 +00:00