Repository navigation
hives: every README held to its code, and what was broken fixed - #100
Merged
Merged
Conversation
A sweep of each hive's README against what its code does, which turned up code that was broken outright; that is fixed here too, each pinned by a test. humd - A connection is heard for nothing but its hello until a breath admits it; before, a connection that never said hello could prompt. - A sid's tones reach only the connections that prompted or attached under it, not every idle bee. - A bloom whose peer leaves the ensemble fails with a retryable `nurse-gone` instead of hanging until it expires. - A refused tool call no longer hangs its cell; per-sid state and sigil claims are freed; a second connection on one key closes the first. hum-nest - `wallClockMs` is enforced; cleanup and eviction act only on their own cell, so a race no longer kills a replacement. hives - grpc listens on 127.0.0.1 by default (it served a bash builder to every interface, unauthenticated). - twilio-sms verifies Twilio's signature. - paid-oracle refuses pending or reverted payments and redeems each once. - gsm-modem, ollama-server, vercel-ai and wifi-p2p start (or build). - anthropic-server, ollama-server and vercel-ai keep history, carry tool calls through, and cancel on disconnect. - Foragers name no model by default, so any nurse with room grows. - Fixes in openai-server, web2, grpc, twilio-sms, dwarfstar, claude-repl. docs - Every hive README, hives/README.md and THRUM.md describe what the code does; foragers.md goes. - hum bee's help names --role.
…md logs at info Installed, a nurse runs under orchd with launchd's PATH, which leaves out ~/.local/bin, where Claude Code's installer puts claude. The nurse nestled and advertised its models, and every prompt failed with "spawn claude". hum_paths::program_dirs looks on PATH and then in ~/.local/bin, ~/.cargo/bin, ~/.bun/bin, /opt/homebrew/bin and /usr/local/bin; both claude hives look there and in ~/.claude/local, take CLAUDE_CLI_PATH first (an empty one is unset), name every place they looked when claude is in none, and take CLAUDE_CLI_PATH from the environment of `hum hive <hive> install`. claude-cli logs which claude it found when it starts. humd logged at trace when HUM_LOG_LEVEL was unset, every iroh frame included, which grew one machine's log past 6 GB and buried the warnings `hum doctor` reads from its tail. It logs at info.
A bee from an older build said hello with no role, humd refused it four times a second for days, and `hum bee --list` showed it as entered, not nestled, advised did-not-return: it had returned, and was refused. Every hello humd refuses now goes through one place that, when the hello names a bee entered here, notes `refused` with the reason and counts the hello toward reconnect-storm, and counts the bee as returned. `hum bee --list` prints the latest reason under a bee that is not nestled. A key nobody entered leaves nothing behind.
…hat started it It was stopped only by a test's close, so a run killed or aborted before then left it serving, reparented to launchd; one had been up for two days. It now reads the pipe its parent holds and exits when that ends.
…e's header The kernel speaks in code: tools/speech.py refuses a field's doc comment.
pnpm 11 refuses an install whose dependencies' build scripts no one approved, and esbuild's is one; anthropic-server already says so.
…he environment of its install The nurse advertised five models from May, so humd routed nothing newer than Opus 4.7, Sonnet 4.6 or Haiku 4.5 to it. It advertises every model served to every account, Fable 5.1 to Haiku 4.5; the Mythos models and the deprecated claude-sonnet-4-5 are for CLAUDE_MODELS to name. The Orchfile takes CLAUDE_MODELS from the environment of `hum hive claude-cli install`, and a value that names no model is unset, so the empty one an install without it passes leaves the built-in list.
adiled
added a commit
that referenced
this pull request
Oct 28, 2026
… words, and a call keeps claude's own id (#102) ## Why Testing #101 in wryme showed one conversation spread over four claude sessions in seven minutes. No claude process piled up, and nothing was lost (each new session got the whole conversation stitched in), but every request that missed began a new sigil and a cold claude session. openai-server (and, since #100, anthropic-server and vercel-ai) found a conversation's sigil by a hash of its whole history: system prompt, every turn's words, every tool id. That is not what a sigil was meant to be (the forager picks the sid), and clients reshape history all the time. What made wryme miss: - on the Responses API, wryme sends claude's tool calls between rounds of a turn but not the words claude said before them, then replays the turn with them; - its `[bookkeeping]` note rides in the system prompt for one request; - `tinker_keep` drops older tool pairs, and a turn can come back squashed into one message. ## What changes **A sigil is found by what the client echoes faithfully** (openai-server, anthropic-server, vercel-ai) 1. A held call's sid, then `previous_response_id` / `conversation`, as before. 2. A line the client names: `X-Hum-Sid` (vercel-ai: `providerOptions.hum.sid`), scoped to the caller. 3. The newest tool call id in the request that this caller was given. Ids are unique, and every client echoes them because it must to answer. 4. The words of the last two turns, which compaction of older turns leaves alone; also tried without trailing answers, so a delivery or a late answer finds the sigil it had before them. 5. Otherwise a new sigil. A sigil continues only from where it last left off: the request must still hold the sigil's newest call (never a call the server ran, which a client may not echo), or match its latest tail. A copy of a conversation taken earlier begins its own. No key reads the system prompt. **claude-cli tells a changed system prompt** at the head of the turn it changes in, and reads what a session was told from its transcript when a cell is raised on it. Before, only a new session was told, so a changed prompt reached claude only by starting a new session. **A call keeps the id its cell gave it.** The nest asks the nurse, `Nurse::call_id` (default none), and knows nothing of any cell. claude-cli reads Claude Code's `_meta["claudecode/toolUseId"]`. A caller, the forager and claude's transcript now name a call alike. Held tool results are matched by call and answer, then by tool and answer; a late answer to a call claude already holds an answer for is stitched on as a call of its own, since a call takes one answer. ## Testing - hum-nest: 34 pass, `tools/speech.py` clean, clippy clean. New: a call keeps the id its cell gave it. - claude-cli: all pass. New: the call id read from `_meta`; a changed system prompt told, an unchanged one not; a transcript says what it was told last; a late answer to a held call stitched as its own call. - openai-server 69, anthropic-server 29, vercel-ai 22, end to end included. `Sigils` tests: dropped older pairs, a squashed turn, mid-turn words missing then present, a changed system prompt, a made-up delivery, a tool-less tail, reordered calls, a server-run last call with `mcp_calls` dropped, all keep the sigil; strangers, a growing sigil, and copies taken earlier (with and without tools) do not; `X-Hum-Sid` names a line per caller. - Live (`HUM_LIVE_CLAUDE=1`, `claude-haiku-4-5`): **20/20**, new: a changed system prompt obeyed on the same sigil (`nurse.cell.reused`); `X-Hum-Sid` carrying a codeword across two unrelated requests; every caller tool call arriving as `toolu_…`. ## Known limits - A client that edits an older message keeps its session, so claude remembers the unedited version. - A copy of a tool-less conversation, taken after its latest turn, shares the original's sigil. - A compaction summary sent as a user message right before the last two turns changes the tail; as a system message it does not.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
A sweep of every hive's README against what its code does turned up code that was broken outright, some of it unsafe. That is fixed here, each fix pinned by a test, and the docs describe the fixed behaviour. Separately, Claude could not be reached through the openai-server hive on an installed humd; the last two commits fix why, and make the failure say so when it happens.
Security
bashbuilder. It listens on127.0.0.1by default.HUM_TWILIO_URL.Could not start, or never worked
Hangs, leaks, lost history
create()), dropped history, and could not carry a tool call through. ollama-server dropped history, hung on tool calls and leaked a connection per request. vercel-ai's tool calls stalled about 10 minutes.nurse-gone; per-sid state grew forever; a second connection on one key did not close the first.wallClockMswas never enforced, and a cleanup race could kill a replacement cell.Claude behind openai-server
On an installed humd, a stale openai-server process was refused by humd four times a second for three days (its hello named no role), and
hum bee --listcalled its beesdid-not-return. Restarted, it nestled, and every request for a claude model failed withspawn claude: the claude-cli nurse runs under launchd'sPATH, which leaves out~/.local/bin, where Claude Code's installer putsclaude.hum_paths::program_dirs/find_program:PATH, then~/.local/bin,~/.cargo/bin,~/.bun/bin,/opt/homebrew/bin,/usr/local/bin. claude-cli and claude-repl look there and in~/.claude/local, takeCLAUDE_CLI_PATHfirst (empty is unset, and their Orchfiles pass it from the environment ofhum hive <hive> install), and name every place they looked when claude is in none. claude-cli logs which claude it found when it starts.refusedadvisory with its reason, counts towardreconnect-storm, and counts the bee as returned.hum bee --listprints the reason under a bee that is not nestled. A key nobody entered leaves nothing behind.tracewhenHUM_LOG_LEVELwas unset, every iroh frame included: one machine's log passed 6 GB and buried the warningshum doctorreads. It logs atinfo.HUM_LOG_LEVELand the claude lookup are inhum(1).Through this branch's openai-server and a nestled claude-cli,
POST /v1/chat/completionsforclaude-haiku-4-5answers, and so does wryme with a shop athttp://127.0.0.1:14620/v1.Left for a decision
hum bee exitdoes not stick: a hive that enters itself re-enters on restart. A test pins it as intended.propensityvalues; the TS client cannot release its link, so vercel-ai closes an idle one after 1 s.echowithok: trueas it arrives and, when refused, a second under the same rid withok: false.Not run for real: no phone, GSM modem, live chain or Twilio account; those paths are tested with fakes.
claude-cli's models: the nurse advertised five models from May, so nothing newer than Opus 4.7, Sonnet 4.6 or Haiku 4.5 reached it through humd. It advertises every model served to every account,
claude-fable-5-1toclaude-haiku-4-5(14); the Mythos models and the deprecatedclaude-sonnet-4-5are forCLAUDE_MODELSto name, whichhum hive claude-cli installnow passes from its environment (empty is the built-in list).Also
pnpm-workspace.yaml, as anthropic-server does, so a freshpnpm installunder pnpm 11 succeeds.hum-nest/src/limits.rsmoved into its//!header (tools/speech.py).Verification, on this branch, macOS arm64:
codegen --check,tools/speech.py,tools/paths.py: pass.sim --test livenessfailed once under load (a handshake timed out while every suite was building at once) and passed 5 of 5 alone; this branch does not touch it.cargo test); twilio-sms (go test -race); openai-server, anthropic-server, vercel-ai (from a cleannode_modules) (bun test); wifi-p2p (gradlew test); dwarfstar (make check): pass.cargo install; claude-cli and openai-server byhum hive <hive> install, noCLAUDE_CLI_PATH): claude-cli finds~/.local/bin/claudeunder launchd'sPATH, openai-server lists all 14 claude models, andwme -pon a station athttp://127.0.0.1:14620/v1answers onclaude-haiku-4-5,claude-sonnet-4-6,claude-haiku-5-5,claude-opus-5-5andclaude-fable-5-1.