hum tee dum tee#43
Open
adiled wants to merge 12 commits into
Open
Conversation
New hum-paths crate. init() sets XDG defaults at startup; every callsite routes through it. No /tmp fallback. Socket moves to $XDG_STATE_HOME/hum.
Issue #41 root cause was Arc<Mutex<Option<Child>>> + try_lock in claude-cli — wait task held the lock forever, kill closure's try_lock always failed, SIGKILL never reached the child. - nest::lifecycle::supervise(AsyncGroupChild) using tokio::select! over child.wait() vs CancellationToken. command-group for tree-kill so claude's descendants die too. Reaps with timeout. - Cell.kill: Arc<dyn Fn> -> Cell.cancel: CancellationToken. - Drop on CellBundle cancels on map removal; idle reaper + LRU evict + map clear all kill correctly. - claude-cli + claude-repl + mock + nest::pool + serve.rs migrated. - lru::LruCache replaces HashMap + linear-scan eviction (O(1)). - nest::metrics swapped /proc parser for sysinfo (cross-platform RSS/CPU). - metrics + metrics-exporter-prometheus on humd; /metrics on 127.0.0.1:9909 (HUM_METRICS_ADDR override). Counters at evict + kill sites; gauge for active cells. - governor token bucket on thrumd accept loop (100/s). - Reconnect jitter on serve_worker reconnect to spread thundering herds. - 3 lifecycle tests: cancel kills, natural exit propagates, tree-kill takes grandchild.
DaemonConfig::from_env() (and a few other early callers) hit hum_paths functions before any init() ran. Tests panicked. Making xdg() call init() on first miss makes init() optional everywhere; explicit init() at bin entry stays as an eager warmup so child processes inherit the env.
Dead modules removed (1500 LOC): - nest::pool (Nest, never used) - nest::mock (only used by pool tests) - nest::health (tiered eviction policy, no callers) - nest::budget (token/tool-call caps, no callers) - nest::Listener + nest::ForagerBee traits (Listener impl in serve.rs was empty stubs; ForagerBee had zero impls) Wired: - nest::metrics::spawn_sampler now drives a hum_cell_rss_bytes / hum_cell_cpu_ms gauge labelled by pid from inside lifecycle::supervise. Per-cell observability stops being a half-built feature. - humd.metricsAddr config knob (hum.json) replaces the hardcoded 127.0.0.1:9909. Schema entry added. Naming standardized: hum_cells_active -> hum_cell_count. Dead code removed in hives/common/src/serve.rs (HashMap import, WireListener Listener impl), humd/src/lib.rs (HumdSink.cli_path), hum/src/main.rs (home() helper). Tests added: - serve::tests::drop_cancels_token — RAII fires on drop - serve::tests::lru_pop_drops_bundle_and_cancels — LRU eviction kills - serve::tests::map_clear_cancels_all — shutdown kills everything - humd::prometheus_endpoint — /metrics actually serves - thrumd::accept_rate_limit — governor paces accepts at quota EOF
…urged, flaky test budgeted - nest::ResourceLimits now actually applied: claude-cli calls apply_pre_exec on the std::process::Command (via cmd.as_std_mut()) before group_spawn. SpawnSpec.resource_limits stops being decorative. - CatalogueSlot.sid: stored but never read. Field + setter param dropped. - humfs::tools::read::is_code_file: production-unused fn with tests testing nothing the codebase uses. Both purged. - partition_then_heal_converges_wane: budget raised 1s -> 10s so the test is no longer load-flaky under parallel runs. cargo check + cargo check --tests: zero warnings.
Rendezvous file (P1 #40 fix): - hum_paths::RuntimeInfo + HumnestRuntimeInfo (atomic write, read, remove). - thrumd::serve_with_hook fires on_bound after UnixListener::bind. humd uses it to publish runtime.json with socket + pid + version + bound_at_ms. - hum_paths::thrum_sock_resolved prefers env > runtime.json > default. Daemons keep thrum_sock; bees/CLI use _resolved. Socket-path drift is gone — clients always reach whatever humd actually bound. - hum doctor connect-tests with a real hello tone, 1s timeout. exists() check replaced. doctor surfaces humnest runtime.json too. - hum bee --list flags "⚠ crash-looping (exit N)" via new svc_last_exit reading systemctl ExecMainStatus / launchctl 'last exit code'. humnest crate — bee supervisor sibling daemon: - Reads humnest.bees[] from hum.json. - Each bee spawned via nest::lifecycle::supervise (group-kill, RAII). - Restart policy per bee: always | on-failure (max_retries, backoff) | never. - Crash-loop state surfaced through humnest-list RPC. - Control socket at humnest.sock (NDJSON): humnest-spawn|humnest-kill|humnest-list. - Sibling to humd: humd crash != humnest crash, bees stay alive. humctl crate — service-manager 0.7 wrapper: - humctl {install|start|stop|restart|status|uninstall} {humd|humnest}. - Pure Rust, ServiceLevel::User, cross-platform via service-manager crate. - scripts/svc.sh DELETED. 300 lines of bash, gone. - ./install + every hives/*/install rewritten to call humctl, drop svc.sh sourcing. Hive install now appends to hum.json humnest.bees + restarts humnest instead of generating per-bee systemd/launchd units. config gained humnest.bees[] schema. hum CLI: new 'hum nest' subcommand lists humnest bees with state + restart count. 'hum bee enter|exit|reenter' routes through humnest first for kinds in hum.json, falls back to legacy svc paths for unknown / 'all' targets. 247 tests pass.
Same priority order as hum_paths::thrum_sock_resolved on the Rust side: HUM_THRUM_SOCK > runtime.json > computed default. Closes the last gap where non-Rust clients would miss humd's published socket path after restart.
humctl shrinks to humd-only operator (no install/uninstall — bootstrap
owns service registration). New verbs: start, stop, restart, status,
logs, health. Status shells systemctl/launchctl native; health does a
real connect + hello/breath probe through hum_paths::thrum_sock_resolved.
hum_paths::macos_log is replaced by daemon_logs(name) returning a typed
DaemonLogs { Journald{unit} | Files{stdout,stderr} } so callers dispatch
on the enum instead of #[cfg]-ing per platform. humctl logs and hum's
print_recent_logs now share the same path.
install bash generates humd.service + humnest.service inline (Linux) or
humd.plist + humnest.plist (macOS), coupling expressed in the unit
files themselves (Wants= / PartOf= / RunAtLoad). svc.sh stays deleted.
SIGHUP reload handler I had added to humnest is reverted — it was a
coarse 'reconcile against disk' plaster. surgical RPC (humnest-spawn /
humnest-kill via the existing control socket) is the right primitive
and hum_route_verb already uses it.
humnest is gone. orchd (sibling Rust project; user-scope systemd +
launchd platform contributed upstream this round) replaces it.
Architecture now:
launchd/systemd
└── humd (one user service; humctl operates; ./install registers)
orchd
└── per-bee user units (one each, generated from per-hive Orchfile)
Hive surface: each hive ships an Orchfile at its root. `hum hive install
<target>` resolves the target, builds (cargo install --path), copies the
Orchfile into ~/.config/hum/orch.d/, re-assembles ~/.config/hum/Orchfile,
and runs `orchd up <kind>`. No more per-hive install bash scripts.
What dies:
- humnest crate (entire thing — 4 modules, supervisor + control + log + lib)
- hum_paths::humnest_sock, humnest_runtime, HumnestRuntimeInfo
- config::HumnestSection, BeeConfig (orch's Orchfile owns this declaration)
- hum.schema.json humnest section
- 4 hives/*/install bash scripts (claude-cli, claude-repl, humfs, paid-oracle)
- ./install humnest unit generation (no second user unit)
What lives:
- humd, humctl, hum CLI: unchanged in role
- humctl: humd operator only (start/stop/status/logs/health)
- orch + orchd: pulled as git deps by ./install via cargo install
What's new:
- hives/{claude-cli,claude-repl,humfs,paid-oracle}/Orchfile (declarative)
- hum CLI: hive_install does build + register-via-Orchfile + orchd up
- hum CLI: bee enter/exit/reenter routes through orchd up/down/restart
- hum CLI: 'hum nest' delegates to 'orchd status'
- ./install pulls orch + orchd from github via cargo install
openai-server (TS) still has its bash install — TS build pipeline
(pnpm install + tsup) not yet automated through hum hive install. Follow-up.
247 tests pass.
Detects build kind by marker file:
- Cargo.toml → cargo install --path
- package.json → pnpm/npm install + build; writes ~/.local/bin/<kind>
as a node wrapper exec'ing the produced dist/index.js
(honors pre-built dist if no pnpm/npm in PATH)
- go.mod → go build -o ~/.local/bin/<kind>
- 'build' script → execute it (escape hatch for exotic hives)
Orchfiles added for the remaining hives (every hive now ships one):
- bp7, grpc, gsm-modem, ollama-server (Rust foragers; bp7-forager,
grpc-forager, ollama-server, gsm-modem binaries)
- openai-server, anthropic-server, vercel-ai (TS HTTP foragers)
- twilio-sms (Go forager)
12 hives total, all surface-uniform: ~/.local/bin/<kind> + Orchfile.
hives/openai-server/install bash deleted — the build pipeline (pnpm
install + tsup build + node wrapper) now lives in hum CLI's
build_node(). One code path for all TS hives.
247 tests pass.
Constitution-level rename. Where hum owns the names, they sing. SpawnSpec → Egg (the thing-to-be a worker raises) WorkerBee::spawn → ::raise (workers raise brood) Cell.pid → Cell.mark (beekeeper's mark) Cell.stdin → Cell.feed (nurses feed larvae through open cells) Cell.events → Cell.mmm (the sounds from inside the cell) Cell.exited → Cell.emerged (adult bee chews out the cap and emerges) Cell.cancel → Cell.silence + Cell.still() (token field, verb method) ResourceLimits → Bounds resource_limits→ bounds CellMetrics → Vitals Attachment → Pollen (what a forager carries home) encode_prompt_with_attachments → encode_prompt_with_pollen nest::lifecycle::supervise → ::tend (nurse bees tend brood cells) Foreign types stay foreign (CancellationToken, mpsc::Sender, AsyncGroupChild, tokio::process::Command, oneshot::Receiver). We don't own those words. Our surface either reads like apiary biology or stays out of the way. 247 tests pass.
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.
No description provided.