Commit Graph

3477 Commits

Author SHA1 Message Date
Timmy 5b48f0d051 fix(897): broaden Bash allowlist to wildcard to stop coders stalling on uncommon commands
The per-command allowlist (Bash(cargo:*), Bash(git:*), …) misses any tool
a coder agent reaches for outside the curated set — ./script/*, make, curl,
jq, docker, test, [, etc. Each miss hits prompt_permission, which auto-denies
on the sled because no listener holds perm_rx (the matrix bot lives in the
gateway). 1,377 such denies in the sled log over the past week, accounting
for most of the recent throughput slowdown.

Replace the curated list with a single Bash(:*) wildcard in:
  - .claude/settings.json (project root, picked up on git worktree add)
  - server/src/io/fs/scaffold/templates.rs (used only by huskies init when
    no .claude/settings.json already exists)

Update scaffold/tests.rs to assert the wildcard rather than a fixed set
of patterns; the per-command gate offered no real safety in this trusted
single-user deployment, since the prompt was never going to reach a human
anyway (that's the bug).

Stopgap until story 898 lands the proper sled→gateway permission
forwarding — at which point the wildcard can be narrowed back if desired.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-05-08 15:14:03 +01:00
Timmy 5248e7ee21 Ignoring some claude session files 2026-05-08 14:42:25 +01:00
dave f8a295eaec huskies: merge 889 2026-05-01 15:02:40 +00:00
dave 61cf7684de huskies: merge 864 2026-04-30 22:27:51 +00:00
dave 3911c24c26 test: drop opus-pin regression test that conflicts with 864's signature change
864 changes write_item_with_content to take 4 args (ItemMeta), but the
master regression test calls the 3-arg form. After 864 squash-merges,
the merged code has the 4-arg fn AND the 3-arg call site, breaking
compile in the merge worktree.

Drop the test for now (the actual run on 864 today validated the fix
end-to-end). Re-add it in a follow-up after 864 lands, using the new
signature.
2026-04-30 22:23:16 +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 66f340a7a3 fix: prune session_store on stdio abort, respawn cold
The bug 882 abort-respawn safeguard caps consecutive crashes at 5 then
blocks the story — but the underlying stdio abort itself stays unfixed:
each respawn calls start_agent which reads session_store.json, finds the
prior session id, passes --resume to claude-code, and re-triggers the
same crash. Five identical respawns later, the story is blocked.

Now: when an abort+no-session exit triggers respawn, we first call
session_store::remove_sessions_for_story to drop every entry for the
story. The next spawn starts cold (no --resume), which avoids the
bloated stdio replay claude-code is choking on.

The function was already implemented but #[cfg(test)] only — promoted
to a non-test pub fn. Existing remove_sessions_for_story_cleans_up test
unchanged and still green.

Net effect: instead of "5 retries, then blocked", we get "1 abort, prune,
respawn cold, agent runs normally". The story can resume work without
losing its worktree state.
2026-04-30 18:19:01 +00:00
dave a8eac3c278 fix: read agent pin from CRDT register, not just YAML front matter
After story 871 the `agent` pin lives in the typed CRDT register
(`PipelineItemView.agent`), not the YAML front matter — the YAML
mutation was removed at the same time. Both spawn-resolution paths
(`auto_assign::story_checks::read_story_front_matter_agent` and
`start::validation::read_front_matter_agent`) still read only YAML
via parse_front_matter, which returns None for any story whose pin
was set via the post-871 typed setter. The spawn then falls back to
"first available coder," silently downgrading opus-pinned stories to
the first available sonnet — which is why 855/864/866 kept hitting the
80-turn watchdog limit despite the user's explicit opus pin.

Now: both paths consult `crdt_state::read_item()` first and use
`view.agent` if non-empty. YAML parsing remains as a fallback so older
stories whose CRDT entry doesn't yet have the field still resolve.

Adds a regression test that seeds an item with empty YAML, sets the
typed CRDT register via `set_agent`, and asserts
`read_story_front_matter_agent` returns the CRDT value.
2026-04-30 16:36:18 +00:00
dave 7a0c186d94 fix(886): parse cargo diagnostics in run_check/run_build/run_lint
Before: tool_run_check (and run_build/run_lint via run_script_tool)
returned the entire cargo log verbatim in `output`. For runs with many
errors the response routinely exceeded the MCP token cap, was dumped
to a tool-results file, and the agent had to scrape it with python3
just to see the error list — burning many turns on file archaeology
for what should be a one-look operation. Real example: 864's coder
hit `result (143,708 characters) exceeds maximum allowed tokens` and
spent ~8 turns extracting 3 errors.

Now:
- New `service::shell::parse_diagnostics` parses `error[CODE]:` /
  `warning[CODE]:` headers + their `--> file:line` markers into
  structured `Diagnostic { kind, code, message, file, line }`.
- `tool_run_check` (and the run_build/run_lint shared body) returns
  `{ passed, exit_code, errors: [...], warnings: [...], summary }`.
  Raw `output` is dropped from the default response.
- New `verbose: bool` argument (default false) restores the raw
  output for callers who actually need it.
- Updated the existing tool_run_check test to assert the new
  contract (150 errors → 150 structured entries, response < 50KB).

Skipped run_tests in this pass — its parser would need to recognise
test-runner output (different format from cargo); will land separately.

Closes 886.
2026-04-30 15:06:02 +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 0e4a970e3a fix(883): canonical Bash(:*) syntax in scaffold settings template
Claude Code 2.1.123+ honours wildcard Bash allowlist patterns only in
the canonical form `Bash(cmd:*)`. The space form `Bash(cmd *)` falls
through to prompt_permission and gets auto-denied in agent mode,
breaking spawned coders.

- Rewrite all `Bash(cmd *)` patterns in STORY_KIT_CLAUDE_SETTINGS to
  the colon form.
- Replace separate `Bash(cargo build:*)` / `Bash(cargo check:*)` with
  a single `Bash(cargo:*)`.
- Add commonly-needed patterns: python3, node, npm, which, sed, awk,
  rg, diff, sort, uniq.
- Patch the live project-root .claude/settings.json so the running
  system picks up the fix immediately (rebuilt scaffolds will match).
- Add regression test asserting no `Bash(... *)` patterns survive and
  required common commands are present.
2026-04-30 13:44:51 +00:00
Timmy 801f9d8a26 Merge branch 'master' of code.crashlabs.io:crashlabs/huskies 2026-04-30 14:38:20 +01:00
Timmy 3a9ff5e740 fix(mcp): restore HTTP /mcp endpoint after 855 regression
855 deleted the HTTP /mcp route and pointed agents at ws://...crdt-sync,
but Claude Code's .mcp.json doesn't speak ws:// and the rendezvous WS
never had MCP method handlers wired up — so every spawned Claude Code
agent (gateway-routed and local) booted with zero huskies tools and
died on --permission-prompt-tool=mcp__huskies__prompt_permission.

Restore mcp_post_handler / mcp_get_handler / handle_initialize, re-add
the /mcp route, and revert all three .mcp.json writers to emit
http://localhost:{port}/mcp with explicit "type": "http". Reuses the
already-extracted gateway::jsonrpc types and the surviving
dispatch_tool_call / list_tools surfaces — net add ~140 lines.

Federation work is unaffected: /crdt-sync continues to do CRDT sync,
which is what it was actually doing. MCP-over-WebSocket for cross-LAN
agents was never wired up by 855 and can be done as a proper follow-up
with a regression test that boots a real claude and verifies tool
registration.

Verified end-to-end: /mcp initialize, tools/list (74 tools incl.
prompt_permission), and tools/call all respond correctly from inside
the rebuilt container.

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
2026-04-30 14:03:16 +01:00
dave b0de86767a huskies: merge 882 2026-04-30 00:35:35 +00:00
dave a796bd933f huskies: merge 879 2026-04-30 00:26:35 +00:00
dave 8fc581ad6b huskies: merge 878 2026-04-29 23:53:15 +00:00
dave 1d86202abb huskies: merge 868 2026-04-29 23:34:24 +00:00
dave e02e566648 huskies: merge 881_bug_inject_prior_gate_failure_output_into_retry_agent_s_system_prompt 2026-04-29 22:52:55 +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 7e2f122d36 huskies: merge 880 2026-04-29 21:46:12 +00:00
dave 4d24b5b661 huskies: merge 855 2026-04-29 21:41:03 +00:00
dave a7b1572693 huskies: merge 856 2026-04-29 21:34:58 +00:00
dave db526bbdb2 huskies: merge 876 2026-04-29 21:20:29 +00:00
dave 56244e8e35 Merge spike branch 'feature/story-814' into master 2026-04-29 20:40:02 +00:00
dave c0801c3894 huskies: merge 875 2026-04-29 18:44:50 +00:00
dave a956a98197 huskies: merge 847 2026-04-29 18:40:08 +00:00
dave 39013be535 huskies: merge 846 2026-04-29 18:24:11 +00:00
dave c50a04445c spike(814): add gateway update command design doc
Documents chat-driven `update` bot command for multi-project gateway:
command surface, auth (room+role guard, future Ed25519), Docker-managed
rollout sequence, automatic and manual rollback, open questions, and
dependencies.
2026-04-29 18:17:19 +00:00
dave 320be659c0 huskies: merge 816 2026-04-29 17:57:34 +00:00
dave 02ebf14828 huskies: merge 845 2026-04-29 17:52:27 +00:00
dave fc86774618 huskies: merge 857 2026-04-29 17:45:51 +00:00
dave 8a42839b37 huskies: merge 820 2026-04-29 17:20:32 +00:00
dave c84786364a huskies: merge 874 2026-04-29 17:00:28 +00:00
dave deffcdc326 huskies: merge 844 2026-04-29 16:29:52 +00:00
dave 8a7e1aa036 huskies: merge 873 2026-04-29 16:11:34 +00:00
dave cf35027b5a config(coders): step 0 — resume prior-session work via git_status + git_log/diff against master..HEAD 2026-04-29 16:03:03 +00:00
dave 9bd3c10a09 huskies: merge 872 2026-04-29 15:59:37 +00:00
dave 7505f7fdeb huskies: merge 843 2026-04-29 15:54:28 +00:00
dave 7f8467b068 huskies: merge 871 2026-04-29 15:45:54 +00:00
dave 2655288412 huskies: merge 870 2026-04-29 15:26:57 +00:00
dave db65271587 huskies: merge 842 2026-04-29 15:10:11 +00:00
dave f3e4d5d072 huskies: merge 869 2026-04-29 14:58:11 +00:00
dave b9bb1ff804 huskies: merge 840 2026-04-29 14:36:50 +00:00
dave d1f58094f8 huskies: merge 839 2026-04-29 14:13:34 +00:00
dave 4324fa7511 huskies: merge 838 2026-04-29 13:58:05 +00:00
dave 59b626d3ba huskies: merge 824 2026-04-29 13:42:58 +00:00
dave b4854cf693 huskies: merge 862 2026-04-29 13:28:37 +00:00
dave 69930fb29f huskies: merge 837 2026-04-29 12:06:09 +00:00