Commit Graph
100 Commits
Author SHA1 Message Date
dave fa54451ba6 huskies: merge 802 2026-04-28 19:05:06 +00:00
dave 5d1e75f7e0 huskies: merge 806 2026-04-28 17:39:29 +00:00
dave efc15c48da huskies: merge 804 2026-04-28 17:34:55 +00:00
dave 691f34348e huskies: merge 805 2026-04-28 17:28:47 +00:00
dave 2f6a221f09 fix(test): stub WebSocket in setupTests so rpcCall fails fast
770's HTTP→read-RPC migration replaced fetch-based agent calls with
rpcCall over WebSocket. setupTests.ts only mocks fetch though, so the
real jsdom WebSocket runs — and jsdom's WebSocket implementation
asynchronously fires its connection-failure error after ~9 seconds
(via internal Timeout._onTimeout). Tests that await component-mount
state (like App.test.tsx > calls getCurrentProject() on mount) hang
on that pending promise and time out at 10s.

This silently broke 1 test on master (App.test.tsx getCurrentProject
on mount) and cascaded into 16 failures in any worktree where the
test file count changed and timing shifted (804, 806).

Fix: replace the global WebSocket constructor with a stub that
immediately fires onerror + onclose on the next microtask. rpcCall
sees the error and rejects synchronously; components catch and continue
rendering with empty state. Tests pass without flake.

Verified locally: vitest run → 349/349 pass.
2026-04-28 17:05:53 +00:00
dave 619bdd9c82 huskies: merge 801 2026-04-28 16:43:04 +00:00
dave 3ff361bfe8 chore: silence git init defaultBranch hints in script/test
Tests that create temp repos call `git init` without specifying a branch.
Git then prints a 12-line "hint: Using 'master' as the name for the
initial branch..." block — every test, every run. The output drowns out
actual failures.

Set init.defaultBranch=master via GIT_CONFIG_COUNT/KEY/VALUE env vars in
script/test. This affects only subprocesses spawned by the test runner;
no change to the user's real git config.

Verified: cargo test --bin huskies emits 0 `hint:` lines after this
change, all 2732 tests still pass.
2026-04-28 16:38:43 +00:00
dave 30dd4b3a0a huskies: merge 796 2026-04-28 16:34:10 +00:00
dave a65cd86c8f huskies: merge 798 2026-04-28 16:25:33 +00:00
dave 1e40215c3e huskies: merge 797 2026-04-28 16:06:50 +00:00
dave d0b7db6765 huskies: merge 785 2026-04-28 15:59:50 +00:00
dave 32a3465fc4 fix: tell the truth about run_tests being blocking
`tool_run_tests` in `server/src/http/mcp/shell_tools/script.rs` is fully
blocking server-side: it spawns the test child, polls every 1s server-side
until exit (or `TEST_TIMEOUT_SECS = 1200s`), and returns the full
{passed, exit_code, output} directly. There is NO async/started-status
return path.

But two places told agents the wrong story:
1. `tools_list/system_tools.rs` description claimed "Returns immediately
   with status: started. Poll get_test_result..." — agents read tool
   descriptions for protocol semantics, so they followed this and burned
   turns polling get_test_result.
2. `agents.toml` had been correctly saying it blocks, but my last commit
   (776aad38) "fixed" it the wrong way based on a misread of the code.

Now both say: run_tests blocks server-side, returns the full result, do
not poll get_test_result. get_test_result remains for external observers
(UI checking on a job another caller started).

Reverts the prompt change in 776aad38 with the correct text.
2026-04-28 15:59:06 +00:00
dave 776aad3877 fix: agent prompts honest about run_tests being async
Pre-f958f57e, run_tests blocked until completion. After that fix it became
a background-job starter, with get_test_result polling. The agent prompts
were never updated, so they still said "run_tests blocks until complete"
— and agents then waste turns polling.

Updated coder-1/2/3, coder-opus, and qa prompts to describe the actual
flow: run_tests is async, get_test_result blocks for up to 20s per call,
test suites typically take 1-5 minutes so expect a few polls.

Companion bug filed for bumping TEST_POLL_BLOCK_SECS so one poll covers
most test runs (root-cause fix; this commit is the prompt half).
2026-04-28 15:55:15 +00:00
dave 309d330734 huskies: merge 794 2026-04-28 15:53:33 +00:00
dave bb779a0b0f chore: regenerate STACK.md source map from module doc-comments
Walked server/src/, frontend/src/, and crates/, extracting each module's
//! doc-comment to build a directory-level source map. One row per
directory + one row per top-level file.

Replaces the hand-written stopgap from 5d6757dd with content auto-derived
from the codebase, so it stays useful as decomposes happen — the
descriptions come from mod.rs, not from my recollection of where things
live.

Still a stopgap until 819 (auto-generated source-map-gen) lands and gets
wired into the agent spawn path, but the content is closer to what 819
will produce.
2026-04-28 15:50:29 +00:00
dave bf17fc14af huskies: merge 795 2026-04-28 15:45:10 +00:00
dave 5d6757dd65 chore: restore source map in STACK.md (stopgap for 818 regression)
818 stripped the source map because it had stale paths. Empirically that
made coder agents far slower — they spent most of each session re-discovering
the codebase via Read/Grep before reaching any Edit, and ran out of turn
budget without committing.

Restoring a fresh source map keyed off current master. Uses directories
where possible so it stays useful through future decomposes, plus a
"Canonical examples" section pointing at the patterns to copy when adding
new CRDT collections, RPC handlers, services, chat commands, etc.

This is a stopgap until 819 (auto-generated source-map-gen) lands.
2026-04-28 15:43:44 +00:00
dave f63464852b huskies: merge 770 2026-04-28 15:38:34 +00:00
dave 1946709681 huskies: merge 788 2026-04-28 15:28:31 +00:00
dave f62012ee9c huskies: merge 793 2026-04-28 15:21:51 +00:00
dave c1a50eab8e huskies: merge 790 2026-04-28 15:16:01 +00:00
dave 7cd9706c0f huskies: merge 813 2026-04-28 14:22:19 +00:00
dave 3772c0d03c huskies: merge 784 2026-04-28 14:07:42 +00:00
dave cf470f5048 huskies: merge 776 2026-04-28 14:01:18 +00:00
dave 8f23d13ac8 huskies: merge 779 2026-04-28 13:48:40 +00:00
dave aed29b952c huskies: merge 769 2026-04-28 13:42:47 +00:00
dave 36ca8d5e3b huskies: merge 827 2026-04-28 13:01:48 +00:00
dave b7db6d6aae huskies: merge 775 2026-04-28 12:25:59 +00:00
dave e9ed58502a huskies: merge 771 2026-04-28 12:08:44 +00:00
dave e879d6f602 huskies: merge 818 2026-04-28 12:03:01 +00:00
dave 6c2bdde695 huskies: merge 783 2026-04-28 11:17:40 +00:00
dave d70719e23c huskies: merge 781 2026-04-28 11:12:24 +00:00
dave 05d057a40a huskies: merge 782 2026-04-28 11:02:02 +00:00
dave 01169332b3 huskies: merge 774 2026-04-28 10:51:59 +00:00
dave 7faacb6664 huskies: merge 773 2026-04-28 10:24:04 +00:00
dave 83f7e41932 huskies: merge 780 2026-04-28 10:19:38 +00:00
dave 0c2789b2c1 huskies: merge 768 2026-04-28 10:12:27 +00:00
dave fb5a21cfbb huskies: merge 778 2026-04-28 10:01:10 +00:00
dave d2d5ef8afa huskies: merge 764 2026-04-28 09:54:47 +00:00
dave 3d986a733b huskies: merge 763 2026-04-28 09:42:59 +00:00
dave 8a51dbd2ed huskies: merge 765 2026-04-28 09:33:23 +00:00
dave 38e828979c huskies: merge 766 2026-04-28 08:59:13 +00:00
dave 0d14fffe1c huskies: merge 762 2026-04-28 01:31:16 +00:00
dave de5b585157 huskies: merge 761 2026-04-28 01:11:07 +00:00
dave 70aaffc2ab huskies: merge 777 2026-04-28 00:33:14 +00:00
dave d1a2393b32 huskies: merge 760 2026-04-28 00:22:29 +00:00
dave 63ce7b9ec3 huskies: merge 759 2026-04-28 00:07:04 +00:00
dave 9b24c2e281 huskies: merge 743 2026-04-27 23:48:53 +00:00
dave bf1393fa60 huskies: merge 741 2026-04-27 23:44:32 +00:00
dave 7ee542dd1e huskies: merge 757 2026-04-27 23:36:56 +00:00
dave dffa05d703 huskies: merge 689 2026-04-27 23:30:55 +00:00
dave 571a057f52 huskies: merge 688_refactor_decompose_server_src_crdt_snapshot_rs_1182_lines 2026-04-27 22:42:48 +00:00
dave 225c4f2b46 huskies: merge 758 2026-04-27 22:21:00 +00:00
dave 03738f35f5 huskies: merge 687_refactor_decompose_server_src_crdt_sync_server_rs_1186_lines 2026-04-27 22:16:08 +00:00
daveandClaude Opus 4.7 574df48ff3 huskies: merge 686_refactor_decompose_server_src_io_watcher_rs_1202_lines
Manual merge resolution: feature branch deleted watcher.rs and split
into watcher/{mod,events,sweep,tests}.rs, while master modified the
old watcher.rs (738's FS-shadow stripping). The auto-resolver kept
both, producing an ambiguous-module compile error.

Resolution: drop watcher.rs (feature's delete wins). The new
watcher/mod.rs absorbs the FS-shadow code semantically — gates pass
(cargo check, clippy --all-targets -D warnings, fmt --check, 29/29
io::watcher tests).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:55:04 +00:00
dave be7b7025d5 huskies: merge 742_refactor_read_rpc_frame_multiplexer_on_crdt_sync_websocket 2026-04-27 21:27:10 +00:00
daveandClaude Opus 4.7 c1bb5888a8 config: bump mergemaster max_turns 60->100, budget $15->$25
Mergemaster needs more headroom for heavy merges (e.g. the slug-to-numeric
ID migration touching many files, or the FS-shadow deletion stories that
require fixing test setup across the codebase). 60 turns wasn't enough
for the larger ones.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:20:22 +00:00
daveandClaude Opus 4.7 191883fe2a config: brutalist refactor guidance + bump mergemaster inactivity_timeout
- Append to all coder/opus system_prompts: for delete/signature-change
  refactors, delete first and let compiler errors guide the call-site
  walk; do not pre-read files predicting breakage. Reduces exploration
  overhead on mechanical refactors.

- Bump mergemaster inactivity_timeout_secs 300 -> 900 (15 min) so
  mergemaster survives the 5-minute API rate-limit backoff. Without
  this, mergemaster gets killed for inactivity while waiting on rate
  limit clear, blocking all merges.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 21:19:09 +00:00
dave 88f9e5dd54 huskies: merge 731_refactor_migrate_existing_stories_from_slug_based_ids_to_numeric_only 2026-04-27 20:42:21 +00:00
dave 1388658ae8 huskies: merge 730_story_use_numeric_only_story_ids_across_mcp_worktrees_git_branches_and_log_paths 2026-04-27 20:22:47 +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 615e1c7f73 huskies: merge 738_refactor_delete_fs_shadow_code_from_lifecycle_rs_and_the_work_directory_watcher 2026-04-27 19:56:53 +00:00
dave 63a30a9319 huskies: merge 736_story_drain_and_prepend_buffered_status_events_on_the_user_s_next_agent_message 2026-04-27 19:37:39 +00:00
dave aa7b26a24a huskies: merge 728_story_cryptographic_peer_handshake_with_trusted_keys_gating 2026-04-27 19:22:55 +00:00
dave ded8c6fd66 huskies: merge 685_refactor_decompose_server_src_config_rs_1223_lines 2026-04-27 19:16:25 +00:00
dave 26f9f3f7fc huskies: merge 729_story_store_story_name_as_a_crdt_field_separate_from_the_story_id 2026-04-27 19:09:56 +00:00
dave 4aadf4aa47 huskies: merge 684_refactor_decompose_server_src_http_agents_rs_1249_lines 2026-04-27 18:49:53 +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 80661fa622 huskies: merge 727_story_ed25519_node_identity_keypair_generation_persistence_and_identity_endpoint 2026-04-27 18:37:58 +00:00
dave b008235d0d huskies: merge 683_refactor_decompose_server_src_agents_pool_start_mod_rs_1329_lines 2026-04-27 18:26:31 +00:00
dave 646dc490b8 huskies: merge 720_refactor_add_mesh_status_mcp_tool_read_only_peer_mesh_diagnostics 2026-04-27 18:18:51 +00:00
dave c6bc6f07f7 huskies: merge 725_story_auto_swap_oauth_account_on_rate_limit 2026-04-27 18:12:57 +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 d654f55981 huskies: merge 682_refactor_decompose_server_src_agents_merge_squash_rs_1346_lines 2026-04-27 17:58:04 +00:00
dave 101f616346 huskies: merge 719_refactor_stale_merge_job_lock_recovery_on_new_merge_attempts 2026-04-27 17:46:49 +00:00
dave 1ecb4dad55 huskies: merge 724_story_per_account_oauth_credential_storage_with_login_pool 2026-04-27 17:40:53 +00:00
dave ed8646f0d9 huskies: merge 681_refactor_decompose_server_src_agents_pool_pipeline_advance_mod_rs_1509_lines 2026-04-27 17:35:17 +00:00
dave 875096b3ec huskies: merge 718_refactor_stale_agent_claims_time_out_claim_ttl_with_displacement 2026-04-27 17:26:51 +00:00
dave 77081926d1 huskies: merge 715_refactor_decompose_frontend_src_components_workitemdetailpanel_tsx_827_lines 2026-04-27 17:08:26 +00:00
dave fce7e16811 huskies: merge 716_story_statuseventbuffer_bounded_per_instance_buffer_over_services_status_broadcaster 2026-04-27 17:03:12 +00:00
dave 2b28ccbf2c Merge spike branch 'feature/story-679_spike_migrate_inter_component_http_to_signed_crdt_websocket_bus' into master 2026-04-27 17:01:48 +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 39a9766d7d huskies: merge 677_refactor_reject_promotion_to_current_coder_of_work_items_with_junk_only_acceptance_criteria 2026-04-27 16:30:35 +00:00
daveandClaude Opus 4.7 5884dac825 chore: gitignore .huskies/session_store.json (runtime artifact)
Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:59:33 +00:00
daveandClaude Opus 4.7 0b7f7dfdf7 config: bump sonnet coder-1/2/3 max_turns 50→80
Stories like the broadcaster-consumer migrations legitimately need ~60
substantive turns (16 ProjectConfig initializer sites + main.rs subscriber
+ reading existing patterns to mirror). 50 was too tight.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-27 14:56:24 +00:00
dave 756c790b9f spike 679: document HTTP-to-CRDT-bus migration plan
Full inventory of all gateway and project server endpoints with caller,
purpose, latency/freshness/durability requirements. Classifies each as
write/read/external-webhook/frontend-asset. Maps write endpoints to
target CRDT collections, proposes RPC frame shapes for read endpoints,
drafts the unsigned read-RPC protocol (envelope, correlation IDs, TTL,
error codes, peer-offline handling), lists in-memory state needing CRDT
migration with proposed types, and defines a wave-ordered migration plan
with explicit dependencies (story 665 Ed25519 auth as the blocker for
write migrations).
2026-04-27 14:49:38 +00:00
dave 6a582d73b6 huskies: merge 675_bug_mergemaster_silently_exits_when_feature_branch_has_zero_commits_ahead_of_master 2026-04-27 14:43:54 +00:00
dave ea872fa01c huskies: merge 676_bug_apply_and_persist_silently_drops_ops_when_persist_channel_send_fails 2026-04-27 14:38:11 +00:00
dave cbb0a50729 huskies: merge 649_story_migrate_whatsapp_transport_to_status_broadcaster 2026-04-27 14:19:19 +00:00
dave 6c8043d866 huskies: merge 648_story_migrate_discord_transport_to_status_broadcaster 2026-04-27 14:01:32 +00:00
dave 9040d18f50 huskies: merge 664_story_crdt_lamport_clock_inner_seq_must_resume_from_max_own_author_seq_1_instead_of_resetting_to_1_on_restart_phase_c 2026-04-27 12:30:44 +00:00
dave 25603bb8cb huskies: merge 669_story_migrate_slack_transport_to_status_broadcaster 2026-04-27 11:57:06 +00:00
dave 5da29c3d91 huskies: merge 668_bug_pipeline_advances_coder_work_to_merge_when_gates_passed_false 2026-04-27 11:39:11 +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 ac85cfce5d huskies: merge 652_story_pass_resume_session_id_on_agent_respawn_so_new_sessions_inherit_prior_reasoning 2026-04-27 11:27:50 +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 56c979c950 config: tell mergemaster to use 5-min sleeps between merge_agent_work polls
Real cause of mergemaster turn-burnout: not merge conflicts, just polling
overhead. The server-side tool_merge_agent_work IS designed to block until
the merge completes, but the MCP client times out after 60s. The agent
then polls get_merge_status, with 30-60s sleeps between polls — each
poll cycle costs 2 turns (sleep + tool call). The merge takes 5-10 min
for a clean run, so the agent burns 10-20 turns just waiting.

Updated workflow tells mergemaster:
- 'operation timed out' is normal, do NOT immediately re-call (would queue
  a duplicate merge)
- Use Bash sleep 300 (one 5-min wait = 1 turn) between polls
- Cap at 3 polls = 15 minutes total, plenty for any clean merge
- Reserve turns for actual fix-up work if gates fail

Combined with the earlier 30→60 turn / $5→$15 budget bump, this should
land any merge with no real conflicts in 3-5 turns total. Plenty of
headroom remaining for genuine gate-fix work.
2026-04-27 10:50:44 +00:00
dave 7b305ba892 config: bump mergemaster max_turns 30→60, budget $5→$15
30 turns is too tight for non-trivial merge gate failures. Combined with
the 3-retry cap, stories with any post-merge fix-up needed (cargo fmt
nits, slightly out-of-date diffs after parallel merges, etc.) get
permanently blocked.

This is a stopgap until story 668 lands (which will keep gates_passed=false
work in the coder stage entirely, so mergemaster only ever sees clean
diffs and the original 30 turns / $5 is fine again).
2026-04-27 10:41:45 +00:00
dave 7408cc5b4b fix(crdt_snapshot): per-thread SNAPSHOT_STATE in cfg(test) instead of shared static (bug 669)
Replaces the test-time GLOBAL_STATE_LOCK approach (which was just disguised
single-threading) with proper test isolation: each test thread gets its own
SnapshotState via a thread_local!.

Pattern matches crdt_state::CRDT_STATE_TL — production keeps the global
OnceLock; tests get a per-thread OnceLock that's accessed through a
snapshot_state() helper. The unsafe `&*ptr` cast to 'static is safe because
the thread_local lives as long as the spawning test thread.

The race: latest_snapshot_available_after_compaction captured at_seq from a
freshly-generated snapshot, then asserted it equalled SNAPSHOT_STATE's
latest.at_seq. With shared SNAPSHOT_STATE, another test thread's
apply_compaction could overwrite latest_snapshot between capture and read.
Per-thread state eliminates the race at its source.

ALL_OPS / VECTOR_CLOCK stay shared — the tests don't assert on absolute
counts, only on (this-thread's at_seq) == (this-thread's latest.at_seq).

5 consecutive default-parallel `cargo test --bin huskies` runs all green
at 2636/2636.
2026-04-27 02:49:53 +00:00