Commit Graph

117 Commits

Author SHA1 Message Date
dave 4e007bb770 huskies: merge 1009 2026-05-13 22:55:05 +00:00
dave 580480094e huskies: merge 984 2026-05-13 16:47:51 +00:00
dave 184c214c34 huskies: merge 962 2026-05-13 12:05:01 +00:00
dave 8b53e20ca9 huskies: merge 961 2026-05-13 11:27:21 +00:00
dave 396a47d7c2 huskies: merge 957 2026-05-13 10:07:49 +00:00
dave a7840ea4b0 huskies: merge 946 2026-05-13 08:00:49 +00:00
dave 9ce5a8df0c huskies: merge 945 2026-05-13 06:09:34 +00:00
dave 7ca5339450 huskies: merge 944 2026-05-13 05:07:28 +00:00
dave 12ae7ec8bb huskies: merge 936 2026-05-12 21:48:39 +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
Timmy 69d91d7707 feat(929): delete db/yaml_legacy.rs entirely — CRDT is the sole source of truth
Final 929 sweep: every YAML-shaped helper is gone. No production code
parses or writes YAML front matter anywhere.

Surface removed:
- db/yaml_legacy.rs (FrontMatter/StoryMetadata structs, parse_front_matter,
  set_front_matter_field, yaml_residue marker) — file deleted.
- ItemMeta::from_yaml — deleted; callers pass typed ItemMeta::named(...) or
  ItemMeta::default() and use typed CRDT setters (set_depends_on,
  set_blocked, set_retry_count, set_agent, set_qa_mode, set_review_hold,
  set_item_type, set_epic, set_mergemaster_attempted) for the rest.
- write_coverage_baseline_to_story_file + read_coverage_percent_from_json —
  the coverage_baseline YAML field was write-only (nothing read it back);
  removed along with its caller in agent_tools/lifecycle.rs.
- update_story_in_file's generic `front_matter` HashMap parameter —
  tool_update_story now intercepts every known field name and routes it
  to a typed CRDT setter; unknown keys are rejected with an explicit error
  pointing at the typed setters. The function only takes user_story /
  description sections now.
- All 117 ItemMeta::from_yaml callsites migrated. Where tests previously
  passed a YAML-shaped content blob and relied on the helper to extract
  name/depends_on/blocked/agent/qa, they now pass:
    write_item_with_content(id, stage, content, ItemMeta::named("Foo"))
    crate::crdt_state::set_depends_on(id, &[...])    // when needed
    crate::crdt_state::set_blocked(id, true)         // when needed
    crate::crdt_state::set_agent(id, Some("..."))    // when needed
- write_story_content + write_story_file (test helper) now take an
  explicit `name: Option<&str>` instead of parsing it from content.
- db::ops::move_item_stage stopped re-parsing YAML on every stage
  transition; metadata is read straight from the CRDT view when mirroring
  the row into SQLite.

New CRDT setters added for symmetry:
- crdt_state::set_name (mirrors set_agent — explicit name updates).

cargo fmt --check, clippy --all-targets -- -D warnings, and the
2830-test suite all pass.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 20:55:25 +01:00
dave f9f16d6a14 huskies: merge 925 2026-05-12 18:33:13 +00:00
dave 03a99b3cf1 huskies: merge 927 2026-05-12 17:55:12 +00:00
Timmy 9eb5116f7e wip(929): stage 2 — migrate chat/transport/matrix/* off yaml_legacy
delete.rs, start.rs, assign.rs all looked up the story name by reading
the content from disk/store and parsing the front matter. Replaced with
`crdt_state::read_item(&story_id).and_then(|w| w.name())`. Each callsite's
fallback chain ("CRDT → content store → filesystem") still locates the
story_id; only the name extraction moved off YAML.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-12 18:45:25 +01:00
dave 9be438e6d3 huskies: merge 865 2026-05-08 14:29:06 +00:00
dave 61cf7684de huskies: merge 864 2026-04-30 22:27:51 +00:00
dave 1251b869a6 style: cargo fmt on today's new code (883/884/886/opus-pin)
The mergemaster gates run rustfmt and rejected 864's merge because
several files I added/touched in master today had not been fmt'd.
Six files affected, mostly trivial line-wrapping nits. Fixes the
formatting gate for the next 864 merge attempt.
2026-04-30 22:15:37 +00:00
dave 7ac3fc2e3e feat(884): persistent perm_rx lock-holder for Matrix bot
Before: handle_message.rs acquired services.perm_rx only while processing
one chat message and dropped it on chat_fut completion. The moment the
bot wasn't actively responding, prompt_permission auto-denied any spawned
coder bash call as "no interactive session" — making unattended coder
work impossible.

Now: a permission_listener task is spawned at bot startup and holds
perm_rx for the bot's lifetime. Permission requests are forwarded to
the first configured Matrix room, replies resolved by the existing
on_room_message handler via pending_perm_replies. Per-message acquire is
gone from handle_message.rs (chat_fut just awaits cleanly).

- New module: chat/transport/matrix/bot/permission_listener.rs.
- Wired into run_bot before BotContext construction; bot_sent_event_ids
  is hoisted out so the listener and the rest of the bot share it.
- handle_message.rs no longer touches perm_rx.
- diagnostics/permission.rs comment updated to reflect the new reality.
- Regression test asserts the listener forwards a PermissionForward to
  the target room and records the pending reply key — exactly the path
  that was broken when no chat_fut was in flight.

Discord/Slack/WhatsApp transports still acquire perm_rx per message
(commands.rs:368 / commands/llm.rs:83 / commands/llm.rs:82). They are
not the active transport in this deployment so their per-message acquire
remains dormant; the same listener pattern should be applied to them as
follow-up work in 884 phase 2.
2026-04-30 13:53:46 +00:00
dave 1d86202abb huskies: merge 868 2026-04-29 23:34:24 +00:00
dave 9a3f60d5d3 huskies: merge 866 2026-04-29 22:47:53 +00:00
dave a49f668b5a huskies: merge 867 2026-04-29 22:17:08 +00:00
dave e56bd2d834 huskies: merge 877 2026-04-29 22:10:47 +00:00
dave db526bbdb2 huskies: merge 876 2026-04-29 21:20:29 +00:00
dave c0801c3894 huskies: merge 875 2026-04-29 18:44:50 +00:00
dave fc86774618 huskies: merge 857 2026-04-29 17:45:51 +00:00
dave c84786364a huskies: merge 874 2026-04-29 17:00:28 +00:00
dave 7f8467b068 huskies: merge 871 2026-04-29 15:45:54 +00:00
dave 59b626d3ba huskies: merge 824 2026-04-29 13:42:58 +00:00
dave 11d111360d huskies: merge 858 2026-04-29 10:47:18 +00:00
dave 39bdbbd095 huskies: merge 809 2026-04-29 00:06:42 +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 d0b7db6765 huskies: merge 785 2026-04-28 15:59:50 +00:00
dave b7db6d6aae huskies: merge 775 2026-04-28 12:25:59 +00:00
dave 0d14fffe1c huskies: merge 762 2026-04-28 01:31:16 +00:00
dave 63d5a500de huskies: merge 670_refactor_hoist_chat_history_persistence_into_a_shared_module_replaces_658 2026-04-27 20:09:44 +00:00
dave 4b64bc614f huskies: merge 726_story_notify_chat_transports_when_oauth_account_swaps_or_all_accounts_are_exhausted 2026-04-27 18:44:47 +00:00
dave 272a592a4d huskies: merge 735_story_attach_statuseventbuffer_to_each_agent_session_scoped_per_project_reset_on_restart 2026-04-27 18:06:11 +00:00
dave 4a0f57478c huskies: merge 671_refactor_migrate_pipeline_state_consumers_from_string_comparisons_to_typed_pipelinestage_enum 2026-04-27 16:39:39 +00:00
dave 65d2fb210c huskies: merge 655_bug_matrix_bot_spawns_its_own_timerstore_instead_of_using_shared_appcontext_timer_store 2026-04-27 11:32:51 +00:00
dave 144f07f412 huskies: merge 644_story_chat_transport_consumers_slack_discord_whatsapp_matrix_for_the_unified_status_broadcaster 2026-04-27 11:22:52 +00:00
dave 75533225e4 fix: commit minor fmt residue blocking mergemaster cherry-picks
Master had 8 uncommitted single-line whitespace changes (blank-line trimming
in test mod headers, etc.) left over from a previous mergemaster cargo-fmt
run that didn't get committed. Each subsequent merge attempt hit:

  cherry-pick failed: 'Your local changes to the following files would be
  overwritten by merge. Please commit your changes or stash them.'

So merges had been silently un-mergeable for the last several rounds —
mergemaster correctly reported the issue but had no way to fix master's
own state from inside the merge_workspace.

Files affected (all whitespace-only):
- chat/transport/matrix/bot/messages/{handle_message,on_room_message}.rs
- chat/transport/slack/commands/{llm,mod}.rs
- http/mcp/agent_tools/worktree.rs
- http/workflow/story_ops/{create,criterion,update}.rs

cargo clippy --all-targets -- -D warnings: clean
cargo fmt --all --check: clean
2636 tests pass.
2026-04-27 11:17:31 +00:00
dave 404fd396f5 refactor: split chat/transport/whatsapp/commands.rs (837) into mod + llm
The 837-line commands.rs is split:

- llm.rs: handle_llm_message (LLM turn for non-command messages, ~195 lines)
- mod.rs: handle_incoming_message + tests (~660 lines)

Tests stay co-located with handle_incoming_message in mod.rs. All 2636 tests pass; clippy clean.
2026-04-27 02:37:22 +00:00
dave 1f02de8cd0 refactor: split chat/transport/slack/commands.rs (875) into mod + llm
The 875-line commands.rs is split:

- llm.rs: handle_llm_message (LLM turn for non-command messages, ~190 lines)
- mod.rs: SlackSlashCommandPayload + slash_command_to_bot_keyword + handle_incoming_message + tests (~700 lines)

Tests stay co-located with handle_incoming_message in mod.rs. All 2636 tests pass; clippy clean.
2026-04-27 02:32:11 +00:00
dave d07728f22b refactor: split chat/transport/matrix/bot/messages.rs (912) into mod + on_room_message + handle_message
The 912-line messages.rs is split:

- on_room_message.rs: incoming Matrix event dispatch (~600 lines)
- handle_message.rs: LLM turn + reply streaming (~265 lines)
- mod.rs: format_user_prompt + tests (~70 lines)

Tests stay co-located with format_user_prompt in mod.rs.

All 2636 tests pass; clippy clean.
2026-04-27 02:21:54 +00:00
dave c600b94f4e chore: remove dangling orphan files accidentally added in b340aa97
server/src/agents/pool/lifecycle.rs and server/src/chat/transport/matrix/notifications.rs were untracked leftovers from an abandoned WIP stash that 'git add -A' picked up. Neither is declared as a mod anywhere — they're dangling code that doesn't get compiled but pollutes the tree.
2026-04-27 01:32:38 +00:00
dave b340aa97b0 fix: clean up clippy warnings + cargo fmt across post-refactor surface
The 13-file refactor pass (commits db00a5d4 through eca15b4e) introduced
~89 clippy errors and 38 cargo fmt issues — every agent in every worktree
hit them on script/test, burning their turn budget on cleanup before doing
real story work. This is the silent kill behind 644, 652, 655, 664, 667
all hitting watchdog limits this round.

Changes:
- cargo fmt --all across 37 files (formatting normalisation only)
- #![allow(unused_imports, dead_code)] on 24 split modules where the
  python-script splitter imported liberally to be safe; tighter cleanup
  per-import will happen as agents touch each module
- Removed truly-dead re-exports (cleanup_merge_workspace, slog_warn from
  http/mcp/mod.rs, CliArgs/print_help from main.rs)
- Prefixed _auth_msg in crdt_sync/server.rs (handshake helper return is
  bound but not consumed)
- Converted dangling /// doc block in crdt_sync/mod.rs to //! so it
  attaches to the module
- Removed empty lines after doc comments in 4 spots (clippy lint)

All 2636 tests pass; clippy --all-targets -- -D warnings clean.
2026-04-27 01:32:08 +00:00
dave a86448f6a6 refactor: split chat/transport/matrix/config.rs into mod.rs + loading.rs
The 1260-line config.rs is split into:

- mod.rs: BotConfig struct + small impl + default helpers + tests (1047 lines)
- loading.rs: BotConfig::load + save_ambient_rooms (223 lines)

Tests stay co-located.

No behaviour change. All 41 matrix::config tests pass; full suite green.
2026-04-26 21:37:39 +00:00
dave d8f9be5b23 huskies: merge 641_story_unified_status_update_delivery_across_chat_web_ui_and_top_level_agent_context 2026-04-26 02:27:34 +00:00
dave 14b158d0b2 huskies: merge 629_refactor_migrate_commanddispatch_and_commandcontext_to_services_bundle 2026-04-25 20:41:19 +00:00