Commit Graph
3976 Commits
Author SHA1 Message Date
TimmyandClaude Fable 5 3ed3fdd6b0 Fold GatesFailed auto-retry into the block subscriber's shared budget
Code review of 1185 (merge 0f4b0c95) found the retry subscriber's central
invariant did not hold: the MergeFailure->Merge bounce caused by its own
retry reset both its attempt counter and the block subscriber's counter,
so the shared merge_failure_block_threshold budget was unreachable and a
deterministic gates failure retried forever.

One subscriber now owns one counter driving both policies:

- Counter survives PipelineEvent::MergeRetryStarted bounces (finding 1);
  a third consecutive failure blocks even with retries in between.
- Mixed failure kinds share the single budget (finding 5).
- Retries respect recovery: no counting or scheduling while a mergemaster
  is active, and perform_auto_retry re-checks before firing (finding 2).
- perform_auto_retry applies the same eligibility gates as
  assign_merge_stage (review hold, frozen, blocked, unmet deps) so freeze
  now stops a retry loop (finding 4).
- Per-story scheduling generations invalidate stale sleeping timers
  (finding 6).
- One-shot startup scan schedules a catch-up retry for stories already
  parked in GatesFailed, so restarts no longer strand them (finding 3);
  kept out of the periodic reconciler to avoid re-retrying exhausted
  stories every tick.
- Chat is notified only after the merge actually starts; a failed trigger
  logs instead of claiming a retry ran (finding 7).
- Config reads moved onto spawn_blocking (finding 8, bug 1170 class).

Deletes merge_failure_retry_subscriber.rs; notification plumbing
(WatcherEvent::MergeAutoRetry et al) is unchanged.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-17 13:36:45 +01:00
Huskies Agent c717ae7041 huskies: regen source-map.json 2026-07-17 12:11:27 +00:00
Huskies Agent 0f4b0c9536 huskies: merge 1185 story Bounded auto-retry for GatesFailed merges before requiring human intervention 2026-07-17 12:11:27 +00:00
Huskies Agent 5d672f5bf6 huskies: regen source-map.json 2026-07-17 12:05:04 +00:00
Huskies Agent 043c77f077 huskies: merge 1186 story compact chat command: distill session context deterministically, then reset with a seed 2026-07-17 12:05:04 +00:00
Huskies Agent b241661941 huskies: regen source-map.json 2026-07-17 11:58:37 +00:00
Huskies Agent dac0278218 huskies: merge 1188 story Merge tool results return a summary, not the full gate log (35KB per call) 2026-07-17 11:58:37 +00:00
Huskies Agent ea8e6edc94 huskies: regen source-map.json 2026-07-17 11:49:43 +00:00
Huskies Agent eda14976d0 huskies: merge 1187 story status chat command shows that project's status 2026-07-17 11:49:43 +00:00
Huskies Agent 0d26ac5a2a huskies: regen source-map.json 2026-07-17 11:39:47 +00:00
Huskies Agent 39dd6e0151 huskies: merge 1184 bug Stage transitions never reach the gateway relay: StatusEvent::StageTransition is published only in tests 2026-07-17 11:39:47 +00:00
Huskies Agent 1d71877af6 huskies: merge 1182 bug Sled uplinks all register as 'workspace' — containers never get HUSKIES_PROJECT_NAME 2026-07-17 10:46:22 +00:00
Huskies Agent ae47dd29e8 huskies: merge 1183 story Config parse error hints at misplaced top-level keys after [[component]] 2026-07-17 10:35:40 +00:00
Huskies Agent faa7825799 huskies: merge 1181 refactor Dependency freshness sweep: bump manifest minimums, refresh lockfile, drop dead serde_yaml 2026-07-16 19:07:01 +00:00
Huskies Agent 97ed97885a huskies: regen source-map.json 2026-07-16 18:10:14 +00:00
Huskies Agent de7d22cb9f huskies: merge 1180 story Sled↔gateway goes WS-only: remove the deprecated HTTP fallback paths 2026-07-16 18:10:14 +00:00
Timmy 0e684fb06f Upgrading Docker to include newer node, so front-end builds 2026-07-16 19:03:48 +01:00
Huskies Agent e0ed35adf1 huskies: regen source-map.json 2026-07-16 17:20:20 +00:00
Huskies Agent aebe75cd04 huskies: merge 1179 story Token-authenticated sled→gateway WS uplink (remote-gateway ready) 2026-07-16 17:20:20 +00:00
Huskies Agent 0738005863 huskies: regen source-map.json 2026-07-16 16:22:46 +00:00
Huskies Agent efd0097f76 huskies: merge 1176 bug base_branch fallback hardcodes master instead of auto-detecting 2026-07-16 16:22:46 +00:00
Huskies Agent a4e2d4bc25 huskies: merge 1177 bug project.toml scaffold puts top-level keys after [[component]] so uncommenting them silently no-ops 2026-07-16 16:13:17 +00:00
TimmyandClaude Fable 5 0eacffa08d Install Node 22 from NodeSource in project base image
Bookworm's apt nodejs is 18.x; frontend toolchains after the 2026-07-15
dependency upgrades (vite 7) require Node >= 20, so any sled building a
frontend via build.rs failed. NodeSource nodejs bundles npm, so the
separate apt npm package is dropped.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-16 16:39:51 +01:00
Huskies Agent e5df6232cf huskies: merge 1178 bug MergeFailureFinal is a trap state: successful re-merge cannot mark the story done 2026-07-16 14:19:55 +00:00
Huskies Agent 61acf98909 huskies: regen source-map.json 2026-07-16 14:03:31 +00:00
Huskies Agent 77e0394195 huskies: merge 1169 story Gateway pulls signed artifacts from a release channel into its local store 2026-07-16 14:03:31 +00:00
Huskies Agent 1e0e581bd7 huskies: regen source-map.json 2026-07-16 13:26:03 +00:00
Huskies Agent 0ac68afa4c huskies: merge 1173 story Identity-aware fleet checks: cryptographic node identity in upgrade and health probes 2026-07-16 13:26:03 +00:00
Huskies Agent 489c415fd9 huskies: regen source-map.json 2026-07-16 13:19:20 +00:00
Huskies Agent 18b065f77a huskies: merge 1163 story Replace perm_rx lock-as-presence-signal with a permission router 2026-07-16 13:19:20 +00:00
Huskies Agent 6f8a8ffd87 huskies: merge 1175 bug Flaky tests intermittently fail merge gates 2026-07-16 13:03:05 +00:00
TimmyandClaude Fable 5 6a1ee8377d docs: update stale libsqlite3-sys pin comment for sqlx 0.9 stable
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
2026-07-16 11:46:26 +01:00
Huskies Agent a464febdcb huskies: merge 1174 story Gateway startup announcement reports version and model 2026-07-16 10:11:55 +00:00
Huskies Agent 8ae2eaaad3 huskies: merge 1160 bug Chat bot crash-loops on poisoned Claude Code session resume 2026-07-16 09:51:44 +00:00
Huskies Agent 23f2934e1f huskies: merge 1172 story Add Docker log rotation to project container launch args 2026-07-16 09:44:48 +00:00
Huskies Agent 69df921856 huskies: merge 1170 bug Full tokio runtime stall after unblock → merge auto-assign 2026-07-16 09:10:46 +00:00
TimmyandClaude Fable 5 f73689cfd8 Fix CRDT self-deadlock: read_llm_session re-locked the state mutex
read_llm_session acquired the CRDT_STATE mutex, then called
extract_llm_session_view while holding the guard — which called
our_node_id(), which locks the same non-reentrant std::sync::Mutex.
The thread deadlocks itself and parks forever HOLDING the lock; every
other CRDT user then queues behind it. With light traffic that's a
partial wedge (MCP `show`/content reads hang while /health stays
green); during a CRDT-write burst (unblock → auto-assign) enough
tasks pile up to pin every tokio worker: liveness heartbeat stops,
/health dies, full sled freeze. Root cause of bug 1170's repeated
sled freezes, confirmed by live gdb capture: thread parked in
lock_contended at presence::our_node_id ← read_llm_session ←
event_matches_persona, with all other threads queued on CRDT reads.

Fix: extract_llm_session_view now takes local_sled_id as a parameter;
read_llm_session computes it from the guard it already holds. The
trigger path (event_matches_persona on persona-subscribed WS events)
explains the raciness — it needs a chat/persona event racing a
pipeline transition.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-16 09:46:36 +01:00
Huskies Agent 1a15347b02 huskies: merge 1165 refactor Upgrade matrix-sdk 0.17 to 0.18 2026-07-16 05:14:46 +00:00
Huskies Agent a4bf11dbc1 huskies: merge 1166 refactor Upgrade ed25519-dalek 2 to 3 2026-07-16 01:08:34 +00:00
Huskies Agent 182771192b huskies: merge 1168 refactor Upgrade tokio-tungstenite 0.29 to 0.30 2026-07-16 00:53:47 +00:00
Huskies Agent 0a53c1ff0a huskies: merge 1167 refactor Upgrade garde 0.22 to 0.23 2026-07-16 00:38:34 +00:00
Huskies Agent ca05bd7224 huskies: merge 1164 refactor Lockfile refresh + sqlx alpha-to-stable 2026-07-16 00:13:38 +00:00
Huskies Agent aa977482db huskies: regen source-map.json 2026-07-16 00:03:44 +00:00
Huskies Agent e67eff17ad huskies: merge 1158 story Reject boilerplate user stories at save time 2026-07-16 00:03:44 +00:00
TimmyandClaude Fable 5 6cceec9c26 Disable CRDT debug logging in default features — fixes runtime stalls
logging-list/logging-json were in bft-json-crdt's default feature set,
so every production build printed multi-KB debug dumps on every CRDT
op — executed INSIDE the global CRDT_STATE mutex. A stdout write that
stalls while holding that lock blocks every task touching the CRDT
(tick loop, watchers, MCP, RPC), each one pinning an OS worker thread
until the tokio pool is exhausted: liveness heartbeat stops, /health
dies, zero CPU. This is the mechanism behind bug 1170 (two full-sled
freezes on huskies-server, both seconds after a CRDT write burst, the
second insert's dump truncated mid-print in the log).

The features remain available for CRDT debugging via explicit opt-in.

Also fixes a latent race in persist_tx_send_success_emits_no_warn:
it counted [crdt_persist] warns in the process-global log buffer,
which parallel tests also write to; the debug prints had been acting
as an accidental serializer. Now filters for its own story id.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 18:37:47 +01:00
TimmyandClaude Fable 5 be0c88c801 Pre-check binary writability before accepting an upgrade request
/api/upgrade now verifies the target can be replaced (create + remove
the swap's tmp file) before returning 202. A sled that cannot write
its own binary — e.g. a container predating the /opt/huskies/bin
layout — fails phase 1 of `upgrade all` loudly instead of returning
202, staying healthy, and silently remaining on the old version, which
is exactly what happened on the first fleet deploy.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 17:53:56 +01:00
TimmyandClaude Fable 5 ba0a38d403 Fix WS deadlock: never block on perm_rx in the chat handler
Since story 884 the Matrix permission listener (and the sled uplink,
when configured) hold services.perm_rx for the process lifetime. The
WS chat handler's blocking `lock().await` on that same mutex therefore
parked the entire WS connection loop forever on StartChat: chat_fut was
never polled, RPC frames on the socket were never answered, and
everything queued behind the dispatcher's serial session lock —
wedging /mcp and /rpc while /health stayed green.

Use try_lock instead: if another task already owns permission routing,
run the chat without the local permission-forwarding select arm (a
pending future keeps the select shape unchanged).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 17:17:24 +01:00
TimmyandClaude Fable 5 01b24ff2ae Drop the drain check from upgrade — agent death is routine
Agents die all the time; the pipeline's retry machinery re-queues
their work. Skipping busy sleds just created version skew and manual
retries for no real protection. `upgrade all` now sweeps every sled
unconditionally.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 16:54:55 +01:00
TimmyandClaude Fable 5 f39c4b7c4b Remove all alternate update paths — fleet redeploy is release + upgrade all
Killed:
- rebuild_and_restart (in-container cargo self-compile): the MCP tool,
  the `rebuild` chat command in all four transports, the web-ui bot
  command, and the underlying function. This was the path that caused
  the exec() deadlocks.
- upgrade_sled gateway MCP tool: second entry point to sled upgrades,
  defaulted to serving the gateway's own macOS binary to Linux sleds.
- GET /api/huskies-binary (both sled and gateway route trees): served
  current_exe(), wrong platform when the gateway is macOS. Superseded
  by /api/artifacts/ which now also serves on the gateway route tree.
- `huskies upgrade` CLI subcommand and --source flag: third way of
  doing the same download-and-replace. Escape hatch for a bricked sled
  is `docker cp` + restart.

Kept, distinct jobs: `project-rebuild` (container/image updates),
`rebuild gateway` + script/local-release (gateway self-update).

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 16:46:11 +01:00
TimmyandClaude Fable 5 83f941b77e Revert /app/target binary fallback in entrypoint
Superseded: the running fleet was created by `new project` (no /app
mount), and the one-way upgrade path now replaces the binary at its
canonical install location (/opt/huskies/bin/huskies) directly, so the
entrypoint needs no fallback logic.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_019fHdm92yjvguPi2LiXfLB9
2026-07-15 16:28:32 +01:00