Framework hardening and stabilization (phases 0-6) - #57
Merged
Conversation
The run_once / run_structured / run_once_structured paths bypassed the HITL approval gate and the input/output guardrail pipeline that _run_loop enforces -- so SDK callers (and the CLI orchestrator) could execute gated tools with no approval and leak PII. Route run_once tool calls through the approval gate, run input/output guardrails on all paths, and also guard task.context in _run_loop (an injection hidden there previously bypassed the input guardrail). Extracted shared _apply_input/output_guardrail helpers and added regression tests.
The denylist only matched a handful of suffixes/provider prefixes, so an agent could read DATABASE_URL, PGPASSWORD, REDIS_URL, bare *_KEY (e.g. STRIPE_KEY), SSH_*/GH_* creds, etc. via `env`. Broaden the pattern and err toward over-scrubbing (pass_env=True restores full env for trusted runs).
web_fetch followed redirects to arbitrary URLs with no scheme/host checks, so an agent could reach cloud-metadata (169.254.169.254) or internal services, and resp.text buffered the whole body. Validate the scheme and resolved IP (reject loopback/private/link-local/reserved), re-validate every redirect hop manually, and stream with a byte cap.
…ponsive stop - store.save_session now sets created_at/last_active so the retention janitor (created_at < cutoff) and TTL expiry (last_active) actually collect daemon sessions instead of leaking them forever. - _process_life_events reuses the cached per-agent provider instead of building a fresh, never-closed client per life event (connection leak). - the heartbeat sleep now waits on a stop Event so Ctrl+C/SIGTERM is honored immediately instead of after up to a full heartbeat; removed the dead _pending_shutdown flag.
…ring These are daemon-lifetime singletons whose histories grew without bound: - SpecializationTracker now keys history by agent in a bounded deque (also removes the O(n^2) full-history rescan on every record()). - SwarmLearning keeps a bounded deque of reports (only latest/trend read). - SufferingState trims resolved-stressor history to a cap (it is persisted in checkpoints, so it grew them forever).
… cleanup - MCP server no longer emits notifications/initialized (that is the client's message per the lifecycle spec) and validates required tools/call args with a clear error instead of an opaque KeyError; dropped the unused _request_id field. - git_add inserts '--' before the pathspec so a leading-dash path is a file, not a git option. - plugin loader uniquifies module names by path hash (no same-stem collisions) and pops half-initialized modules from sys.modules on exec failure.
Land daemon lifecycle durability, security boundary closure, operator truth parity, agent cycle decomposition, adversarial test suite, layered CI gates, and docs/plans so merge-ready behavior matches working tree.
Contributor
|
| Filename | Overview |
|---|---|
| .github/workflows/ci.yml | Creates the clean archive destination before extraction, resolving the previously reported build failure. |
| src/hive/tools/url_safety.py | Builds IP-pinned HTTP and HTTPS requests with the original hostname retained for Host and TLS SNI, including valid bracketed IPv6 authorities. |
| tests/runtime/test_web_tools.py | Covers HTTPS IP pinning, Host preservation, SNI selection, and IPv6 authority formatting. |
Reviews (4): Last reviewed commit: "test: prove httpx.stream receives HTTPS ..." | Re-trigger Greptile
Merge origin/main trace/metrics work into framework-hardening, keep the expanded TraceTree API and operator endpoints, adopt main's richer /metrics format, pin HTTPS fetches to validated IPs with SNI, and mkdir the CI clean-build extraction directory.
Add sync/async tests that mock httpx clients and assert request_url_safe_sync and fetch_url_safe pass pinned IP netloc, Host header, and sni_hostname into client.stream(). Bracket IPv6 literals in build_pinned_request so pinned URLs parse correctly.
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.
Summary
24_multi_agent_collaboration,26_structured_extraction,28_toolkit_workshop) and operator tooling (hive doctor, budget CLI parity, secure toolkit factory).Verification
uv run ruff check src/ tests/+ruff format --checkuv run mypy src/(205 files)uv run pytest tests/adversarial/— 243 passeduv run pytest tests/ --cov=hive --cov-fail-under=77— 1865 passed, ~79% coverageuv run mkdocs build --strict[audio]extra)git archive HEAD+uv sync --extra apireproduces full test passTest plan
hive doctor,hive config, daemon start/stopexamples/24_multi_agent_collaboration.pywith API keyNotes
.marshal/,agents/) intentionally not committed.uv buildmay fail in Conductor workspaces due to.conductorsymlinks; usegit archivefor reproducible builds.