Skip to content

feat(guardrail): Batches 1-4 — Agent industrial hardening - #169

Merged
ULookup merged 28 commits into
mainfrom
infra-fixes-2026-06-20
Jun 21, 2026
Merged

feat(guardrail): Batches 1-4 — Agent industrial hardening#169
ULookup merged 28 commits into
mainfrom
infra-fixes-2026-06-20

Conversation

@ULookup

@ULookup ULookup commented Jun 21, 2026

Copy link
Copy Markdown
Owner

Summary

  • Batch 1: Guardrail configurability — TurnGuardConfig, ToolDomain enum, circuit breaker threshold, mutex
  • Batch 2: Sub-agent isolation — profiles mutex, shared_from_this, AgentTool async rewrite, MemoryStore isolation
  • Batch 3: Observability & API — RunMetrics, SSE continuous loop, REST endpoints (list/resume runs), HTTP protection
  • Batch 4: Tool system & context hardening — tool timeout, JSON Schema validation, compactor exception safety, token budget hard enforcement, O(1) user query cache, tool rate limiting, ContextPipeline mutex

Stats

  • 59 files changed, +2554/-175 lines
  • 55 tests pass across 4 test binaries
  • 27 commits on infra-fixes-2026-06-20

Test plan

  • All 55 unit tests pass
  • Build compiles cleanly (no new warnings)
  • Batch 1: TurnGuardConfig defaults, ToolDomain bitflag checks
  • Batch 2: Sub-agent registration, delegation, fan-out, concurrent access
  • Batch 3: RunMetrics, list_runs, SSE subscription
  • Batch 4: JSON Schema validation (missing required, wrong type, valid args), config defaults (tool_timeout_ms, rate limits)

ULookup added 9 commits June 21, 2026 10:23
Covers TurnGuard configurability, sub-agent isolation, observability/API,
and tool/context hardening. References Claude Code permission model and
Codex CLI observability patterns.
8 steps, 26 files, ~200 lines. Covers TurnGuardConfig, ToolDomain flags,
circuit breaker configurability, and mutex hardening.
…omain on all tools, replace hardcoded tool name lists

Steps 1-4 of Batch 1.
…utex for TurnGuard and StallDetector

Steps 5-7 of Batch 1.
Add 12 TurnGuard tests (config defaults, custom thresholds, nudge
messages, warning count, reset) and 5 Batch 1 agent loop tests
(circuit breaker threshold, ToolDomain classification/bitflags).
- profiles_ now protected by std::shared_mutex (unique_lock for writes,
  shared_lock for reads with cfg copy-out before create_sub_agent)
- SubAgentRunner inherits enable_shared_from_this, async lambdas
  capture shared_from_this() instead of raw this
- SubAgentConfig gains max_turns field (0 = use default of 10)
- Each sub-agent gets an isolated MemoryStore (no shared parent state)
- hardware_concurrency() guarded with std::max(1, ...) against zero
- fan_out and sequential now handle per-task exceptions without
  losing completed results
- AgentTool spawn: std::thread().detach() replaced with std::async +
  active_tasks_ map + get_result action + kMaxConcurrentSubAgents=8
@ULookup ULookup changed the title feat(guardrail): Batch 1 — Agent guardrail configurability feat(guardrail): Batch 1+2 — Agent guardrail configurability & sub-agent isolation Jun 21, 2026
@ULookup ULookup changed the title feat(guardrail): Batch 1+2 — Agent guardrail configurability & sub-agent isolation feat(guardrail): Batches 1-3 — Agent industrial hardening Jun 21, 2026
ULookup added 5 commits June 21, 2026 15:04
…imit tests

- test_tools.cpp: 4 new tests for argument validation (missing required, wrong type, valid args, no-schema tool)
- test_agent_loop.cpp: 4 new tests for tool_timeout_ms, tool_rate_limit defaults
- All 55 tests pass across 4 test binaries
@ULookup ULookup changed the title feat(guardrail): Batches 1-3 — Agent industrial hardening feat(guardrail): Batches 1-4 — Agent industrial hardening Jun 21, 2026
ULookup added 8 commits June 21, 2026 16:19
8 fixes across 8 files: run_call_count_ reset, tool timeout abandoned-task
pattern, fan_out error storage, ToolDomain-based tool restriction, dynamic
reason messages, resume_run() execution launch, test fix, agent_tool
capacity check reorder.
10 tasks across 3 parallel worktree groups, ~80 lines in 8 source files,
plus 5 new regression tests.
…est, add regression tests

- agent_tool: move std::async launch after capacity check inside mutex
- test_tools: register ReadFileTool in empty-registry validation test
- turn_guard: use config threshold in world-query reason message
- Add regression tests: restricted_tools default, reason messages, fan_out error handling, run_call_count_
…timeout, ToolDomain restrictions, dynamic reason messages
…ix 6)

Resolved sub_agent_runner.cpp conflict: kept shared_from_this safety and
hardware_concurrency-based max_parallel, added batch_start tracking for
error-to-agent_id mapping in catch block.
…lDomain restrictions, dynamic reasons)

Fix 1: reset run_call_count_ in run(), resume(), restore_history()
Fix 2: abandoned-task container pattern (drain_abandoned_tasks, cancel token, overflow valve)
Fix 4: ToolDomain-based tool restriction replaces hardcoded string list
Fix 5: dynamic reason messages using config threshold values
Added abandoned_tasks to RunMetrics

Reverted WT-A duplicate ToolDomain/domain_of changes (already in Batch 1).
…meta include

Clean up WT-A+WT-B merge artifacts: duplicate RunMetrics struct, duplicate
resume_run declaration/definition, and missing tool_meta.hpp include in
turn_guard.hpp for ToolDomain type.
@ULookup

ULookup commented Jun 21, 2026

Copy link
Copy Markdown
Owner Author

Review Bug Fixes Applied

8 confirmed bugs from code review have been fixed and pushed:

Fix Description Files
1 run_call_count_ reset across runs agent_loop.cpp
2 Tool timeout future destructor blocks → abandoned-task container agent_loop.hpp/cpp
3 fan_out error result stored with agent_id key sub_agent_runner.cpp
4 ToolDomain-based restriction replaces hardcoded tool names turn_guard.hpp/cpp, agent_loop.hpp/cpp
5 Dynamic reason messages with config thresholds turn_guard.cpp
6 resume_run() launches execute_run() runtime_service.hpp/cpp
7 Schema-less validation test registers tool properly test_tools.cpp
8 AgentTool capacity check moved before std::async agent_tool.cpp

Test results: 59/59 passed (AgentLoop: 26, TurnGuard: 14, SubAgentRunner: 9, Tools: 10)

Design doc: docs/superpowers/specs/2026-06-21-review-fixes-design.md
Plan: docs/superpowers/plans/2026-06-21-review-fixes.md

…n text, eval_scene_completeness)

- Adapt to synchronous run()/resume() return types (remove .get() calls)
- Preserve our review fixes: restricted_domains_, run_call_count_ reset, abandoned_tasks
- Add last_compaction_text_ member from main
- Forward-declare eval_scene_completeness (main bug: used before definition)
- Merge compaction logic: keep try/catch + metrics from our branch, last_compaction_text_ from main
@ULookup
ULookup merged commit 6ddc0f4 into main Jun 21, 2026
0 of 6 checks passed
ULookup added a commit that referenced this pull request Jun 21, 2026
Keep main's retry-safe text snapshots, llm_start timing, and improved
exception logging from Agent industrial hardening batch.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant